Imports System.Xml
Imports System.IO
Imports Microsoft.VisualBasic.FileIO
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization
Imports System.Threading
Imports System.Text.RegularExpressions
Imports System.Drawing.Drawing2D
Imports ICSharpCode.SharpZipLib.BZip2
Imports System.Security.Cryptography.HashAlgorithm
Imports System.Security.Cryptography
Imports BikiSoft.DataLogging
Imports Gosubb
<ObfuscationAttribute(Exclude:=True, ApplyToMembers:=True)> _
Public Class frmBikiMain
    Implements DataStream.IStreamRecieve

    Private m_newCar As CarBase = Nothing
    Private m_ptTable As Table = Nothing
    Private m_ptVars As Vars = Nothing
    Private m_ptBVars As BVars = Nothing
    Private m_ptArray() As Byte = Nothing

    Private m_ptSubConfig As SubConfig = Nothing

    Private m_UserDesktopSettings As New UI.UserDesktopSettingsCollection
    Private m_StreamControls As New ObjectModel.Collection(Of INamed)
    Private m_StreamRuntimeExtensions As DataStream.StreamRuntimeControler

    Private m_EmulatorLog As EmulatorLog

    Private m_ReUndo As New States.UnRedo
    Private WithEvents m_Diagnostics As frmDiagnostics = Nothing
    Private WithEvents m_UsbHandler As Comm.UsbCommunicationHandle = Nothing

    Private m_temp() As Byte ' This variable is used to shift data back from the download event
    Private m_currentFile As String
    Private m_saveRequired As Boolean = False

    ''' <summary>
    ''' Bit set integer for the control of threads
    ''' Thread to spawn on return from other threads and what to do
    ''' </summary>
    Shared m_cmdQueue As New Threads.Queue
    Shared m_cmdCurrent As Threads.QueueObj = Nothing

    Shared m_threadPendingAction As mod_BikiUSB.BikiAction = mod_BikiUSB.BikiAction.BK_ALL
    Shared m_threadPendingObject As Object = Nothing

    Private m_ConsultEnable As Boolean = False
    Private m_MapMirror As Boolean = False
    Private m_emuStopStart As Boolean = False

    Private m_ConsultDispDelay As Integer = 0
    Public m_CurrentDisp As Integer = 0
    Private m_RecentFiles As New Recent

    Dim uxBarTop As New WeifenLuo.WinFormsUI.Docking.DockContent()
    Dim uxBarGraph As New WeifenLuo.WinFormsUI.Docking.DockContent()
    Dim uxBarGraph3d As New WeifenLuo.WinFormsUI.Docking.DockContent()
    Dim uxBarInfo As New WeifenLuo.WinFormsUI.Docking.DockContent()

    Dim uxDockGrids As New Generic.List(Of WeifenLuo.WinFormsUI.Docking.DockContent)
    Dim uxDockGridFocus As Controls.DataGrid = Nothing

    Dim uxDockVars As New Generic.List(Of Forms.frmGlobalVars)
    Dim uxDockVarsFocus As Forms.frmGlobalVars = Nothing

    Private Enum boxEnum As Integer
        BOX_VARS = &H1
        BOX_BGRID = &H2
        BOX_GRID = &H4
        BOX_2DGRAPH = &H8
        BOX_GRAPH = &H10
        BOX_INFO = &H20
        BOX_ALL = &H0
    End Enum

#Region "-------------------------------- Initializing, Constructing and Closing Subs/Functions"
    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        'Me.SetStyle(ControlStyles.SupportsTransparentBackColor, False)
        'Application.EnableVisualStyles()
    End Sub

    Private Sub NewBikiMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        My.Settings.Save()

        If Not IsNothing(m_StreamRuntimeExtensions) Then
            m_StreamRuntimeExtensions.Dispose()
        End If

        If Not closeCheckAll() Then
            e.Cancel = True
        Else
            ' Dump the Desktop Settings to file
            Dim userSettingsLoader As New Modules.ObjectPersistance(Of UI.UserDesktopSettingsCollection)(Modules.ObjectPersistance(Of Global.BikiSoft.UI.UserDesktopSettingsCollection).SaveState.Binary)
            userSettingsLoader.SaveToFile(Application.StartupPath & "\Settings\desktop.settings.cfg", m_UserDesktopSettings)
        End If
    End Sub

    ''' <summary>
    ''' Handles all un-handled exceptions!
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ApplicationExceptions(ByVal sender As Object, ByVal e As System.Threading.ThreadExceptionEventArgs)
        Dim form As New frmInformation("Unhandled Exception", "An Unhandled exception occured in BikiSoft. Please report this error to errors@bikirom.com subject: 'Unhandled Exception in BikiSoft'. Please attach this screen dump" _
        & Chr(10) & e.Exception.Source & Chr(10) & e.Exception.StackTrace _
        , "", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly)

        form.Show()
    End Sub

    Private Sub ApplicationClosing(ByVal sender As Object, ByVal e As System.EventArgs)
        RemoveHandler Application.ApplicationExit, AddressOf ApplicationClosing
        RemoveHandler Application.ThreadException, AddressOf ApplicationExceptions

    End Sub

    Private Sub NewBikiMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.SetStyle(ControlStyles.SupportsTransparentBackColor, False)
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(ControlStyles.UserPaint, True)
        Application.EnableVisualStyles()
        My.Settings.Reload()
        ' Load Recently used files
        menu_RecentPopulate()
        If GetRegistryKey("online", False) = True Then
            bConsult.Checked = True
        End If

        ' Assign the application closing event!
        AddHandler Application.ApplicationExit, AddressOf ApplicationClosing
        AddHandler Application.ThreadException, AddressOf ApplicationExceptions

        ' Initialised all the stream controls
        InitialiseFormStreamControls()

        ' Create the USB Communication shit
        If m_UsbCommHandler Is Nothing Then
            m_UsbHandler = New Comm.UsbCommunicationHandle(True)
            m_UsbCommHandler = m_UsbHandler
        Else
            m_UsbHandler = m_UsbCommHandler
        End If

        ' Parse the command line if any
        If m_newCar Is Nothing Then
            If My.Application.CommandLineArgs.Count > 0 Then
                For i As Integer = 0 To My.Application.CommandLineArgs.Count - 2
                    If My.Application.CommandLineArgs(i) = "-f" Then
                        ' next should be filename
                        Dim f_tool As New ToolStripMenuItem
                        f_tool.Tag = My.Application.CommandLineArgs(i + 1)
                        Me.mFopen_Click(f_tool, Nothing)
                    End If
                Next
            End If
        End If

        ' Attempt to re-load the user desktop settings
        Dim userSettings As UI.UserDesktopSettingsCollection
        Dim userSettingsLoader As New Modules.ObjectPersistance(Of UI.UserDesktopSettingsCollection)(Modules.ObjectPersistance(Of Global.BikiSoft.UI.UserDesktopSettingsCollection).SaveState.Binary)
        userSettings = userSettingsLoader.LoadFromFile(Application.StartupPath & "\Settings\desktop.settings.cfg")

        ' Load them in if they are all good! :)
        If Not IsNothing(userSettings) Then
            m_UserDesktopSettings = userSettings
        End If

        ' Re-generate the menu's now
        DesktopSettingsGenerateMenuItems(Me.uxViewDesktopSettings)

        ' Load all the default settings
        DesktopSettingApply(m_UserDesktopSettings.CurrentDesktop)

        ' Load the run-time DLLs
        m_StreamRuntimeExtensions = New DataStream.StreamRuntimeControler()
        AddHandler m_StreamRuntimeExtensions.AddControl, AddressOf Me.InitialiseStreamControl
        AddHandler m_StreamRuntimeExtensions.RemoveControl, AddressOf Me.UnInitialiseStreamControl
        '        addhandler m_StreamRuntimeExtensions.RuntimeExtensionException, addressof Me.
        AddHandler m_StreamRuntimeExtensions.DisplayMessage, AddressOf DisplayMessageHandler

        ' Initialise the extensions
        m_StreamRuntimeExtensions.Initialise()

        'Dim f As Byte() = arrayLoad(Application.StartupPath & "/VQ Maps/Raw VQ data/y32.vq")
        'Dim vq As New vq(f, 500, "Q45 AFM")
        'Dim f_memStream As New MemoryStream()
        'Dim serializer As New BinaryFormatter

        'serializer.Serialize(f_memStream, vq)
        'arrayDump(f_memStream.ToArray, Application.StartupPath & "/VQ Maps/Y32 q45.bvq")

        ' Prepare all the controls into containers
        uxBarTop.Controls.Add(Me.uxFlowTop)
        uxFlowTop.Dock = DockStyle.Fill
        ' Me.uxFlowTop.Dock = DockStyle.Fill
        uxBarTop.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockTop)
        'uxBarTop.MaximumSize = New Size(0, 96)
        uxBarTop.AllowEndUserDocking = False
        uxBarTop.HideOnClose = True
        uxBarTop.TabText = "Display Components"
        uxBarTop.AutoHidePortion = 96
        uxBarTop.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        uxBarTop.DockHandler.CloseButtonVisible = False
        uxBarTop.DockHandler.CloseButton = False

        uxBarGraph.Controls.Add(Me.uxGraphOne)
        uxBarGraph.TabText = "2D Graphing"
        uxBarGraph.HideOnClose = True
        uxGraphOne.Dock = DockStyle.Fill
        uxBarGraph.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom)

        uxBarGraph3d.Controls.Add(Me.boxGraph)
        uxBarGraph3d.TabText = "3D Graphing"
        uxBarGraph3d.HideOnClose = True
        uxBarGraph3d.Icon = Icon.FromHandle(My.Resources.Graph.GetHicon)
        boxGraph.Dock = DockStyle.Fill
        uxBarGraph3d.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.Document Or WeifenLuo.WinFormsUI.Docking.DockAreas.Float
        uxBarInfo.Controls.Add(Me.gbInfo)
        uxBarInfo.TabText = "BikiSoft File Information/settings"
        uxBarInfo.HideOnClose = True

    End Sub
    Private Sub reInitialize()
        GridClose()

        GlobalClose()
        
        'm_cmdQueue = New Threads.Queue
        m_ReUndo = New States.UnRedo
        mFsave.Enabled = False
        mFsaveAs.Enabled = False
        m_saveRequired = False
        'm_car = Nothing
        m_ptTable = Nothing
        m_ptArray = Nothing
        mFimport.Enabled = False
        mfExport.Enabled = False
        openBin.InitialDirectory = Application.StartupPath & "\Base Data\"
        saveCar.InitialDirectory = Application.StartupPath & "\BikiRom Files\"
        openCar.InitialDirectory = Application.StartupPath & "\BikiRom Files\"

        uxDockGridFocus = Nothing

        dgInfo.Rows.Clear()
        m_ptSubConfig = Nothing
        m_CurrentDisp = My.Settings.form_Layout
        box_Display(m_CurrentDisp)
        m_currentFile = ""
    End Sub

    Friend Sub SetTraceColour(ByVal colour As Color)
        For Each control As WeifenLuo.WinFormsUI.Docking.DockContent In Me.uxDockGrids
            Dim DataGrid As Controls.DataGrid = control.Controls(0)

            DataGrid.TraceColour = colour
        Next
    End Sub

    Friend Sub SetEmulatorColour(ByVal colour As Color)
        For Each control As WeifenLuo.WinFormsUI.Docking.DockContent In Me.uxDockGrids
            Dim DataGrid As Controls.DataGrid = control.Controls(0)

            DataGrid.EmuTraceColour = colour
        Next
    End Sub
#End Region

#Region "-------------------------------- Display -= Menu Generating and Menu Item event handlers"
    Private Sub menu_Populate(ByRef Config As CarBase)
        Try
            '' Generate the normal Tables for ECU
            If Not IsNothing(Config) Then
                If Not IsNothing(Config.getConfig) Then
                    Dim onClick_ As System.EventHandler
                    Dim f_tool As ToolStripMenuItem
                    Dim f_count As Integer = 0

                    '' Load Recent Files --------------------------------------------------------------------------------------------------------
                    menu_RecentPopulate()

                    '' Load DataLogging DB ------------------------------------------------------------------------
                    menu_DataLoggingPopulate()

                    '' Load Tables and Variables for ECU ----------------------------------------------------------------------------------------
                    onClick_ = New System.EventHandler(AddressOf mAtable_Click)
                    uxMenuAdjust.DropDownItems.Clear()
                    uxMenuAdjust.DropDownItems.AddRange(New ToolStripItem() {Me.mVglobal, Me.mVUserCalcs, New ToolStripSeparator})
                    Dim f_tabs As Table()

                    For Each tabCont As TableCont In Config.getConfig.getTables.getAsArray
                        If Not IsNothing(tabCont.getFirstTable) Then
                            f_tool = New ToolStripMenuItem(tabCont.Name)
                            If Not IsNothing(tabCont.description) Then f_tool.ToolTipText = tabCont.description.ToolTip
                            f_tabs = tabCont.getAsArray
                            f_tool.DropDownItems.AddRange(menu_GenerateDropDowns(f_tabs, onClick_, Keys.F2 + f_count))
                            uxMenuAdjust.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {f_tool})
                            f_count += 1
                        End If
                    Next
                    f_count = 0
                    mMap1.Enabled = True
                    mMap2.Enabled = True
                    mMap3.Enabled = True
                    uxMenuAdjust.DropDownItems.Add(New ToolStripSeparator)

                    '' Load Bikirom Menu's -----------------------------------------------------------------------------------------------------
                    Config.getBikSettings.ClearSetting(m_newCar.getVars)
                    '' Generate the menu's for the BikiRom shite
                    If Config.getBikSettings.count >= 1 Then
                        Dim f_tables As ToolStripMenuItem
                        Dim f_params As ToolStripMenuItem

                        ' Generate the Drop DownMenu's.. each config then Parameters and Tables
                        onClick_ = New System.EventHandler(AddressOf mBtable_Click)
                        For Each bConfig As SubConfig In Config.getBikSettings.getConfigsAsArray
                            If bConfig.Name = "seperator" Then
                                uxMenuAdjust.DropDownItems.AddRange(New ToolStripItem() {New ToolStripSeparator})
                            Else
                                f_tool = New ToolStripMenuItem(bConfig.Name)
                                f_tool.Tag = bConfig
                                f_tables = Nothing
                                f_params = Nothing
                                If Not IsNothing(bConfig.getTables) Then
                                    f_tables = New ToolStripMenuItem("Tables")
                                    f_tabs = bConfig.getTables.getAsArray
                                    If Not IsNothing(f_tabs) Then f_tables.DropDownItems.AddRange(menu_GenerateDropDowns(f_tabs, onClick_)) Else f_tables = Nothing
                                End If
                                If Not IsNothing(f_tables) Then f_tool.DropDownItems.AddRange(New ToolStripMenuItem() {f_tables})
                                If Not IsNothing(bConfig.getVars) Then
                                    f_params = New ToolStripMenuItem("Parameters", Nothing, AddressOf mBvar_Click)
                                    f_params.Tag = bConfig.getVars
                                End If
                                If Not IsNothing(f_params) Then f_tool.DropDownItems.AddRange(New ToolStripMenuItem() {f_params})
                                f_params = Nothing
                                If bConfig.getBVars <> "" Then
                                    f_params = New ToolStripMenuItem("Settings", Nothing, AddressOf mBvar_Click)
                                    f_params.Tag = bConfig.getBVars
                                End If
                                If Not IsNothing(f_params) Then f_tool.DropDownItems.AddRange(New ToolStripMenuItem() {f_params})
                                uxMenuAdjust.DropDownItems.AddRange(New ToolStripMenuItem() {f_tool})
                            End If
                        Next
                    End If
                End If
            End If

        Catch
            Err_message("Error generating Menu's")
            Err_report(Err.Description)
        End Try
    End Sub
    Private Sub menu_RecentPopulate()
        Dim onClick_ As System.EventHandler
        Dim f_tool As ToolStripMenuItem
        Dim f_count As Integer = 0
        onClick_ = New System.EventHandler(AddressOf mFopen_Click)
        mFrecent.DropDownItems.Clear()

        '' Load Recent Files --------------------------------------------------------------------------------------------------------
        If Not IsNothing(m_RecentFiles) Then
            Dim f_strings() As String = m_RecentFiles.ToArray

            For Each str As String In f_strings
                f_count += 1
                If str <> "" Then
                    If str.Length >= 30 Then
                        f_tool = New ToolStripMenuItem(f_count & ") ...\" & GetFileName(str), Nothing, onClick_)
                    Else
                        f_tool = New ToolStripMenuItem(f_count & ") " & str, Nothing, onClick_)
                    End If
                    f_tool.Tag = str
                    f_tool.ToolTipText = str
                    mFrecent.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {f_tool})
                End If
            Next
        End If
    End Sub

    Private Function menu_GenerateDropDowns(ByRef f_map() As Table, ByRef onClick_ As System.EventHandler) As ToolStripItem()
        Dim image_ As System.Drawing.Image = Nothing
        Dim s_menuitems() As ToolStripItem = Nothing
        Dim s_vars As Vars = Nothing
        Dim s_count As Integer = 0
        If Not IsNothing(f_map) Then
            ReDim s_menuitems(0 To UBound(f_map))
            For Each e_map As Table In f_map
                If Trim(e_map.Name) = "seperator" Then
                    s_menuitems(s_count) = New ToolStripSeparator
                Else
                    s_vars = e_map.Variables
                    If Not IsNothing(s_vars) Then
                        Dim sub_menu As New ToolStripMenuItem(e_map.Name)
                        If e_map.Address >= 0 Then
                            sub_menu.DropDownItems.Add("Table", image_, onClick_)
                        Else
                            sub_menu.DropDownItems.Add("Table", image_)
                            sub_menu.DropDownItems(0).Enabled = False
                        End If
                        sub_menu.DropDownItems(0).Tag = e_map
                        sub_menu.DropDownItems.Add("Variables", image_, AddressOf mBvar_Click)
                        sub_menu.DropDownItems(1).Tag = s_vars
                        s_menuitems(s_count) = sub_menu
                    Else
                        If e_map.Address >= 0 Then
                            s_menuitems(s_count) = New ToolStripMenuItem(e_map.Name, image_, onClick_)
                        Else
                            s_menuitems(s_count) = New ToolStripMenuItem(e_map.Name, image_)
                            s_menuitems(s_count).Enabled = False
                        End If
                    End If
                    If Not IsNothing(e_map.Description) Then s_menuitems(s_count).ToolTipText = e_map.Description.ToolTip
                    s_menuitems(s_count).Tag = e_map
                End If
                s_count += 1
            Next
        End If
        Return s_menuitems
    End Function
    Private Function menu_GenerateDropDowns(ByRef f_map() As Table, ByRef onClick_ As System.EventHandler, ByVal Shortcut As System.Windows.Forms.Keys) As ToolStripItem()
        Dim image_ As System.Drawing.Image = Nothing
        Dim s_menuitems() As ToolStripItem = Nothing
        Dim s_count As Integer = 0
        If Not IsNothing(f_map) Then
            ReDim s_menuitems(0 To UBound(f_map))
            For Each e_map As Table In f_map
                If Trim(e_map.Name) = "seperator" Then
                    s_menuitems(s_count) = New ToolStripSeparator
                Else
                    If s_count = 0 Then
                        s_menuitems(s_count) = New ToolStripMenuItem(e_map.Name, image_, onClick_, Shortcut)
                    Else
                        s_menuitems(s_count) = New ToolStripMenuItem(e_map.Name, image_, onClick_)
                    End If

                    If Not IsNothing(e_map.Description) Then s_menuitems(s_count).ToolTipText = e_map.Description.ToolTip
                    s_menuitems(s_count).Tag = e_map
                End If
                s_count += 1
            Next
        End If
        Return s_menuitems
    End Function
    Private Sub mAtable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ' Try
        Dim f_item As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        If Not IsNothing(f_item.Tag) Then

            m_ptTable = CType(f_item.Tag, Table)
            tmrGraph.Enabled = True

            Dim preName As String = "Map " & m_newCar.CurrentMapNumber + 1 & _
                m_newCar.MapNameFormatted(m_newCar.CurrentMapNumber)

            GridAdd(m_ptTable, m_newCar.CurrentMap, m_newCar, preName)

        End If
        'Catch
        '    Err_message("Error getting tables")
        '    Err_report(Err.Description)
        'End Try
    End Sub
    Private Sub mBtable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Try
            Dim f_tmp As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
            If Not IsNothing(f_tmp.Tag) And Not IsNothing(m_newCar) Then
                m_ptTable = CType(f_tmp.Tag, Table)
                m_ptArray = m_newCar.getBikSettings.Data
                If Not IsNothing(f_tmp.OwnerItem.Tag) AndAlso f_tmp.OwnerItem.Tag.GetType Is GetType(SubConfig) Then
                    m_ptSubConfig = CType(f_tmp.OwnerItem.Tag, SubConfig)
                ElseIf Not IsNothing(f_tmp.OwnerItem.OwnerItem.Tag) AndAlso f_tmp.OwnerItem.OwnerItem.Tag.GetType Is GetType(SubConfig) Then
                    m_ptSubConfig = CType(f_tmp.OwnerItem.OwnerItem.Tag, SubConfig)
                ElseIf Not IsNothing(f_tmp.OwnerItem.OwnerItem.OwnerItem.Tag) AndAlso f_tmp.OwnerItem.OwnerItem.OwnerItem.Tag.GetType Is GetType(SubConfig) Then
                    m_ptSubConfig = CType(f_tmp.OwnerItem.OwnerItem.OwnerItem.Tag, SubConfig)
                End If
                If IsNothing(m_ptSubConfig) Then
                    Throw New Exception("Menu not generated corretly, contact BadBiki")
                End If

                GridAdd(m_ptTable, m_ptArray, m_newCar)

                tmrGraph.Enabled = True
            End If
        Catch
            Err_message("Error getting bikirom Tables")
            Err_report(Err.Description)
        End Try
    End Sub
    Private Sub mBvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Try
            Dim f_tmp As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
            Dim strKey As String = ""
            If Not IsNothing(f_tmp.Tag) And Not IsNothing(m_newCar) Then

                If Not IsNothing(f_tmp.OwnerItem.Tag) AndAlso f_tmp.OwnerItem.Tag.GetType Is GetType(SubConfig) Then
                    m_ptSubConfig = CType(f_tmp.OwnerItem.Tag, SubConfig)
                ElseIf Not IsNothing(f_tmp.OwnerItem.OwnerItem.Tag) AndAlso f_tmp.OwnerItem.OwnerItem.Tag.GetType Is GetType(SubConfig) Then
                    m_ptSubConfig = CType(f_tmp.OwnerItem.OwnerItem.Tag, SubConfig)
                ElseIf Not IsNothing(f_tmp.OwnerItem.OwnerItem.OwnerItem.Tag) AndAlso f_tmp.OwnerItem.OwnerItem.OwnerItem.Tag.GetType Is GetType(SubConfig) Then
                    m_ptSubConfig = CType(f_tmp.OwnerItem.OwnerItem.OwnerItem.Tag, SubConfig)
                End If
                If IsNothing(m_ptSubConfig) Then
                    Throw New Exception("Menu not generated corretly, contact BadBiki")
                End If

                If f_tmp.Tag.GetType Is GetType(Vars) Then
                    GlobalAdd(CType(f_tmp.Tag, Vars).Description, m_newCar.getBikSettings.getData, CType(f_tmp.Tag, Vars))
                    'GlobalAdd(f_tmp.OwnerItem.Text & " - " & CType(f_tmp.Tag, Vars).Description, m_newCar.getBikSettings.getData, CType(f_tmp.Tag, Vars))
                ElseIf f_tmp.Tag.GetType Is GetType(String) Then
                    'GlobalAdd(f_tmp.OwnerItem.Text & " - Settings", m_newCar.getVars, m_ptSubConfig.getBVars)
                    GlobalAdd(f_tmp.OwnerItem.Text & " - Settings", m_newCar.getVars, m_ptSubConfig.getBVars)
                End If

            End If
        Catch ex As Exception
            Err_message("Error getting bikirom variables")
            Err_report(Err.Description)
        End Try
    End Sub

    'Private Sub menu_DataLogging_DropDownPopulate(ByRef mnuItem As ToolStripMenuItem, ByRef dlDb As DataLogging.ConsultLogDB, ByRef dlItem As DataLogging.ConsultLog)
    '    If Not IsNothing(mnuItem) And Not IsNothing(dlDb) Then
    '        Dim fMenuItem(3) As ToolStripItem
    '        fMenuItem(0) = New ToolStripMenuItem("Open", Nothing, New System.EventHandler(AddressOf mDstream_Open))
    '        fMenuItem(0).Tag = mnuItem.Tag
    '        fMenuItem(1) = New ToolStripSeparator()
    '        fMenuItem(2) = New ToolStripMenuItem("Delete", Nothing, New System.EventHandler(AddressOf mDstream_Delete))
    '        fMenuItem(2).Tag = mnuItem.Tag
    '        fMenuItem(3) = New ToolStripMenuItem("Join")
    '        fMenuItem(3).Tag = mnuItem.Tag
    '        menu_DataLogging_DropDownDropDownPopulate(fMenuItem(3), dlDb, dlItem)
    '        mnuItem.DropDown.Items.AddRange(fMenuItem)
    '    End If
    'End Sub
    'Private Sub menu_DataLogging_DropDownDropDownPopulate(ByRef mnuItem As ToolStripMenuItem, ByRef dlDb As DataLogging.ConsultLogDB, ByRef dlItem As DataLogging.ConsultLog)
    '    If Not IsNothing(mnuItem) And Not IsNothing(dlDb) And Not IsNothing(dlDb) Then
    '        If dlDb.Count >= 2 Then
    '            Dim fMenuUtem(dlDb.Count - 2) As ToolStripItem
    '            Dim fCount As Integer = 0
    '            For i As Integer = 0 To dlDb.Count - 1
    '                If dlDb(i).Header <> dlItem.Header Then
    '                    fMenuUtem(fCount) = New ToolStripMenuItem(dlDb(i).HeaderTxt, Nothing, New System.EventHandler(AddressOf mDstream_Join))
    '                    fMenuUtem(fCount).Tag = i
    '                    fCount += 1
    '                End If
    '            Next
    '            mnuItem.DropDown.Items.AddRange(fMenuUtem)
    '        End If
    '    End If
    'End Sub
    Private Sub mVDStreams_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs)
        menu_DataLoggingPopulate()
    End Sub

#End Region

#Region "-------------------------------- Display -= Main Tables Grid Display, refresh and event handlers"

    Private Sub GridAdd(ByRef Table As BikiSoft.Table, ByRef Array As Byte(), ByRef Car As CarBase, Optional ByVal preName As String = "")
        Dim box As New WeifenLuo.WinFormsUI.Docking.DockContent()
        Dim grid As New BikiSoft.Controls.DataGrid()

        For Each control As WeifenLuo.WinFormsUI.Docking.DockContent In Me.uxDockGrids
            Dim DataGrid As Controls.DataGrid = control.Controls(0)

            If DataGrid.Table Is Table AndAlso Array Is DataGrid.Data Then
                Console.Write("Table already on display")
                Exit Sub
            End If
        Next

        'grid.Dock = DockStyle.Fill
        If preName <> "" Then
            box.TabText = preName & " - " & Table.Name
        Else
            box.TabText = Table.Name
        End If
        box.Controls.Add(grid)
        box.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.Document Or WeifenLuo.WinFormsUI.Docking.DockAreas.Float

        box.Icon = Icon.FromHandle(My.Resources.Grid.GetHicon)

        ' Initialise the Grid
        'grid.Dock = DockStyle.Fill
        box.AutoScroll = True

        With grid
            Dim DataGridViewCellStyle1 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Dim DataGridViewCellStyle2 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Dim DataGridViewCellStyle3 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Dim DataGridViewCellStyle4 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle

            .TraceColour = My.Settings.TraceColour
            .EmuTraceColour = My.Settings.EmuTraceColour
            .AllowUserToAddRows = False
            .AllowUserToDeleteRows = False
            .AllowUserToResizeColumns = False
            .AllowUserToResizeRows = False
            .AutoSize = True
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
            DataGridViewCellStyle1.Font = New System.Drawing.Font("Microsoft Sans Serif", 11.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, CType(0, Byte))
            DataGridViewCellStyle1.ForeColor = System.Drawing.Color.Black
            DataGridViewCellStyle1.Format = "N0"
            DataGridViewCellStyle1.FormatProvider = New System.Globalization.CultureInfo("en-AU")
            .AlternatingRowsDefaultCellStyle = DataGridViewCellStyle1
            .BackgroundColor = System.Drawing.SystemColors.Control
            .BorderStyle = System.Windows.Forms.BorderStyle.None
            .CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None
            .ColumnDescription = ""
            '.ColumnHeadersHeight = 20
            .ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing
            .DataRefreshTime = 0
            DataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter
            DataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window
            DataGridViewCellStyle2.Font = New System.Drawing.Font("Microsoft Sans Serif", 11.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, CType(0, Byte))
            DataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ButtonFace
            DataGridViewCellStyle2.Format = "N1"
            DataGridViewCellStyle2.FormatProvider = New System.Globalization.CultureInfo("en-AU")
            DataGridViewCellStyle2.NullValue = Nothing
            DataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight
            DataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText
            DataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.[False]
            .DefaultCellStyle = DataGridViewCellStyle2
            .DoubleBuffering = True
            .EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter
            .EmuTraceColour = System.Drawing.Color.Red
            .EmuTracePoints = Nothing
            .EmuTraceWidth = 2.0!
            .FindNearest = False
            .GetCurrentStreamLog = Nothing
            ' .Location = New System.Drawing.Point(5, 20)
            ' .Margin = New System.Windows.Forms.Padding(4)
            ' .Name = "DataGrid"
            .ReadOnly = True
            .RowDescription = ""
            DataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft
            DataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control
            DataGridViewCellStyle3.Font = New System.Drawing.Font("Microsoft Sans Serif", 11.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, CType(0, Byte))
            DataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText
            DataGridViewCellStyle3.FormatProvider = New System.Globalization.CultureInfo("en-AU")
            DataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight
            DataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText
            DataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.[True]
            .RowHeadersDefaultCellStyle = DataGridViewCellStyle3
            ' .RowHeadersWidth = 50
            .RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing
            DataGridViewCellStyle4.ForeColor = System.Drawing.Color.Black
            DataGridViewCellStyle4.Format = "N0"
            DataGridViewCellStyle4.FormatProvider = New System.Globalization.CultureInfo("en-AU")
            DataGridViewCellStyle4.NullValue = Nothing
            DataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.GradientInactiveCaption
            DataGridViewCellStyle4.SelectionForeColor = System.Drawing.Color.White
            .RowsDefaultCellStyle = DataGridViewCellStyle4
            '.RowTemplate.Height = 19
            .SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect
            .ShowEditingIcon = False
            .TabIndex = 0
            .Text = "DataGrid"
            .TraceColour = System.Drawing.Color.Green
            .TraceWidth = 1.0!
            .VirtualMode = True
            '.Dock = DockStyle.Fill
            .Visible = True
            .Name = Table.Name
            .BringToFront()

        End With
        box.BackColor = System.Drawing.SystemColors.Control

        ' ToDo: Check this works OK
        box.DockHandler.TabPageContextMenuStrip = grid.ContextMenuStrip
        'box.ContextMenuStrip = grid.ContextMenuStrip

        ' hook the functions
        AddHandler box.Activated, AddressOf GridGotFocus
        AddHandler box.GotFocus, AddressOf GridGotFocus
        AddHandler box.FormClosing, AddressOf GridClosing
        AddHandler grid.SelectionChanged, AddressOf dGrid_SelectionChanged

        ' populate the grid
        grid.populate(Car, Table, Array)

        ' Add to the Update Streams
        Me.InitialiseStreamControl(grid)

        ' Add to the colelction of grids
        uxDockGrids.Add(box)

        ' show the control
        box.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
    End Sub

    Private Sub GridClosing(ByVal sender As Object, ByVal e As Windows.Forms.FormClosingEventArgs)
        If uxDockGrids.Contains(sender) Then
            Dim grid As Controls.DataGrid = CType(sender, WeifenLuo.WinFormsUI.Docking.DockContent).Controls(0)
            Me.UnInitialiseStreamControl(grid)
            uxDockGrids.Remove(sender)
        End If
    End Sub

    Private Sub GridGotFocus(ByVal sender As Object, ByVal e As EventArgs)
        Try
            uxDockGridFocus = CType(sender, WeifenLuo.WinFormsUI.Docking.DockContent).Controls(0)

            Dim pTable As Table = CType(CType(sender, WeifenLuo.WinFormsUI.Docking.DockContent).Controls(0), Controls.DataGrid).Table

            If Not IsNothing(pTable) Then
                m_ptTable = pTable
            End If

            tmrGraph.Enabled = True

            If Not IsNothing(Me.m_newCar.getConfig.getTables.getTableByName(pTable.Name)) _
            Or pTable.EmulatorAble Then
                'ToDo: Finish of this find if its a car table
                If Me.m_UsbHandler.IsConnected And Me.m_UsbHandler.Initialised And Me.m_UsbHandler.BoardVersion = Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV3 Then
                    Dim tm As Integer = m_UsbHandler.Timeout
                    m_UsbHandler.Timeout = 500
                    Dim frame As New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, pTable.Address / 2, Comm.Comm_Frame.BikiFrameAction.RUN_SET_TRACE_ADR, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                    If m_UsbHandler.SendFrame(frame, , False, 1) = Comm.Comm_Frame.BikiFrameResponse.CMD_OK Then
                        Err_message("Trace Enabled for " & m_ptTable.Name, message_type.MSG_Infomation)
                    End If
                    m_UsbHandler.Timeout = tm
                End If
            End If

        Catch ex As Comm_Exceptions
            Debug.Print("Unable to set trace point")
        Catch ex As USB_exceptions
            Debug.Print("Unable to set trace point")
        End Try
    End Sub

    Private Sub grid_Populate()

        'On Error Resume Next
        For Each Control As WeifenLuo.WinFormsUI.Docking.DockContent In Me.uxDockGrids
            Dim grid As Controls.DataGrid = CType(Control, WeifenLuo.WinFormsUI.Docking.DockContent).Controls(0)
            grid.populate()
        Next

    End Sub

    Private Sub dGrid_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tmrGraph.Enabled = False
        tmrGraph.Enabled = True
    End Sub

    ''' <summary>
    ''' Close all the Open Grids
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GridClose()
        If uxDockGrids.Count Then
            For i As Integer = uxDockGrids.Count To 1 Step -1
                uxDockGrids(i - 1).Close()
            Next
        End If
    End Sub

#End Region

#Region "-------------------------------- Display -= Main Variables Grid Display, refresh and event handlers"
    ''' <summary>
    ''' Adds a new global variables grid to the main form
    ''' </summary>
    ''' <param name="Vars"></param>
    ''' <param name="key"></param>
    ''' <remarks></remarks>
    Private Sub GlobalAdd(ByVal Name As String, ByVal Vars As BVars, Optional ByVal key As String = "")
        For Each form As Forms.frmGlobalVars In Me.uxDockVars
            If form.CompareTo(Vars) Then Exit Sub
        Next

        Dim frm As New Forms.frmGlobalVars(Me.m_newCar, Vars, key)
        uxDockVars.Add(frm)
        frm.TabText = Name
        frm.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)

        AddHandler frm.RefreshMenuItems, AddressOf GlobalRefreshMenuItems_EventHandler
        AddHandler frm.Activated, AddressOf GlobalFocus
        AddHandler frm.FormClosing, AddressOf GlobalClosing
        AddHandler frm.GotFocus, AddressOf GlobalFocus
    End Sub

    Private Sub GlobalAdd(ByVal Name As String, ByVal Data As Byte(), ByVal Vars As Vars)
        For Each form As Forms.frmGlobalVars In Me.uxDockVars
            If form.CompareTo(Vars, Data) Then Exit Sub
        Next

        Dim frm As New Forms.frmGlobalVars(Me.m_newCar, Data, Vars)
        uxDockVars.Add(frm)
        frm.TabText = Name
        AddHandler frm.RefreshMenuItems, AddressOf GlobalRefreshMenuItems_EventHandler
        AddHandler frm.Activated, AddressOf GlobalFocus
        AddHandler frm.FormClosing, AddressOf GlobalClosing
        AddHandler frm.GotFocus, AddressOf GlobalFocus
        frm.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
    End Sub

    Private Sub GlobalClosing(ByVal sender As Object, ByVal e As Windows.Forms.FormClosingEventArgs)
        If uxDockVars.Contains(sender) Then
            Dim frm As Forms.frmGlobalVars = sender
            uxDockVars.Remove(frm)
            RemoveHandler frm.RefreshMenuItems, AddressOf GlobalRefreshMenuItems_EventHandler
            RemoveHandler frm.Activated, AddressOf GlobalFocus
            RemoveHandler frm.FormClosing, AddressOf GlobalClosing
            RemoveHandler frm.GotFocus, AddressOf GlobalFocus
        End If
    End Sub

    Private Sub GlobalFocus(ByVal sender As Object, ByVal e As EventArgs)
        If uxDockVars.Contains(sender) Then
            uxDockVarsFocus = sender
        End If
    End Sub

    Private Sub GlobalRefreshMenuItems_EventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
        menu_Populate(Me.m_newCar)
        GlobalPopulate()
    End Sub

    ''' <summary>
    ''' Causes all the currently opened global varialbe forms to open
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GlobalPopulate()
        For Each frm As Forms.frmGlobalVars In Me.uxDockVars
            frm.Reload()
        Next
    End Sub

    ''' <summary>
    ''' Causes all the global variables displays to close
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GlobalClose()
        If Me.uxDockVars.Count Then
            For i As Integer = Me.uxDockVars.Count To 1
                Me.uxDockVars(i - 1).Close()
            Next
        End If
    End Sub

#End Region

#Region "-------------------------------- Control/Thread -= Display(group boxes) and Thread Control"

 
    Private Sub box_Add(ByVal display As boxEnum)
        m_CurrentDisp = m_CurrentDisp Or display
        box_Display(m_CurrentDisp)
    End Sub
    Private Function box_Check(ByVal display As boxEnum) As Boolean
        If m_CurrentDisp And display Then
            Return True
        Else
            Return False
        End If
    End Function
    Private Sub box_Remove(ByVal display As boxEnum)
        If display = boxEnum.BOX_ALL Then m_CurrentDisp = 0
        m_CurrentDisp = (display Xor &HFFFFFFFF) And m_CurrentDisp
        box_Display(m_CurrentDisp)
    End Sub
    Private Sub box_Toggle(ByVal display As boxEnum)
        If m_CurrentDisp And display Then box_Remove(display) Else box_Add(display)
    End Sub
    Private Sub box_Display(ByVal display As boxEnum)
        'If display And boxEnum.BOX_2DGRAPH Then LibGraph2D1.Visible = True : LibGraph2D1.Visible = True : mV2Dtrace.Checked = True Else LibGraph2D1.Visible = False : LibGraph2D1.Visible = False : mV2Dtrace.Checked = False
        If display And boxEnum.BOX_GRAPH Then
            Me.uxBarGraph3d.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
            tmrGraph.Enabled = True
        Else
            Me.uxBarGraph3d.Hide()
            tmrGraph.Enabled = False
        End If
        '' ToDo: Remove this comment, re-able for no docking things
        'If display And boxEnum.BOX_GRID Then
        '    Me.uxBarCarGrid.TabText = Me.dGrid.Text
        '    Me.uxBarCarGrid.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
        'Else
        '    Me.uxBarCarGrid.Hide()
        'End If
        If display And boxEnum.BOX_INFO Then
            Me.uxBarInfo.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
        Else
            Me.uxBarInfo.Hide()
        End If
    End Sub
    'Private Sub mV3d_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mV3d.Click
    '    If mV3d.Checked Then  Else 
    'End Sub
    Private Sub mV3d_CheckStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mV3d.CheckStateChanged
        Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        If menuItem.Checked Then
            Me.uxBarGraph3d.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
        Else
            Me.uxBarGraph3d.Hide()
        End If
    End Sub
    Private Sub mV3d_VisibleChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mV3d.VisibleChanged
        Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        If box_Check(boxEnum.BOX_GRAPH) Then
            menuItem.Checked = True
        Else
            menuItem.Checked = False
        End If
    End Sub
    'Private Sub mV2Dtrace_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mV2Dtrace.Click
    '    If mV2Dtrace.Checked Then box_Add(boxEnum.BOX_2DGRAPH) Else box_Remove(boxEnum.BOX_2DGRAPH)
    'End Sub
    Private Sub mV2Dtrace_CheckStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mV2Dtrace.CheckStateChanged
        Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        If menuItem.Checked Then
            uxBarGraph.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom)
            'If Me.uxBarGraph.IsHidden Then
            '    uxBarGraph.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom)
            'Else
            '    Me.uxBarGraph.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockBottom
            'End If
            'Me.uxMiddleSplitter.Panel2Collapsed = False
        Else
            Me.uxBarGraph.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockBottomAutoHide
            'Me.uxMiddleSplitter.Panel2Collapsed = True
        End If
    End Sub
    Private Sub mV2Dtrace_VisibleChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mV2Dtrace.VisibleChanged
        Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        If box_Check(boxEnum.BOX_2DGRAPH) Then
            menuItem.Checked = True
        Else
            menuItem.Checked = False
        End If
    End Sub

#End Region

#Region "-------------------------------- Control/Refresh -= Main Menu button Event Handlers"
    Private Sub cnFNewFromConsult_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnFNewFromConsult.Click
        Dim form As New frmConsultDownload(m_UsbCommHandler)
        form.Show()
    End Sub
    Private Sub mFsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFsave.Click
        'Try
        ' Import all arrays into the car class
        If m_currentFile <> "" Then

            ' New file extension
            If m_currentFile.EndsWith(".bik") Then
                m_currentFile = m_currentFile.Replace(".bik", ".bik2")
                stFile.Text = GetFileName(m_currentFile)
            End If

            '--------------------------- PrePare object for Save -------------------------------------
            m_newCar.SaveCurrent()
            dumpBikFile(m_newCar, m_currentFile)
            m_saveRequired = False
            Err_message("Saved : " & m_currentFile)
        Else : MsgBox("No current file to Save to, Try Save As")
        End If
        ' Catch
        'MsgBox("File IO Error, Not saved!")
        'Err_message(Err.Description)
        'end Try
    End Sub
    Private Sub mFsaveAs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFsaveAs.Click
        'show open dialog
        saveCar.Title = "Save BikiRom File"
        saveCar.Filter = "*.bik2 BikiR0M file|*.bik2|*.bbd BikiRom Base Data Template|*.bbd"
        saveCar.InitialDirectory = Application.StartupPath & "\BikiRom Files\"
        'saveCar.DefaultExt = "bik"
        saveCar.AddExtension = True
        If saveCar.ShowDialog() = Windows.Forms.DialogResult.OK Then
            'Dim fil As New File
            'fil.
            Dim f_str As String = GetExtension(saveCar.FileName)
            Select Case f_str
                Case "bik2"

                    'Try

                    '--------------------------- PrePare object for Save -------------------------------------
                    m_newCar.SaveCurrent()
                    dumpBikFile(m_newCar, saveCar.FileName)

                    m_currentFile = saveCar.FileName
                    mFsave.Enabled = True
                    m_RecentFiles.Add(openCar.FileName)
                    menu_RecentPopulate()

                    m_currentFile = saveCar.FileName

                    Err_message("Saves as : " & saveCar.FileName)

                    Me.Text = "BikiS0FT - " & m_currentFile
                    stFile.Text = GetFileName(m_currentFile)
                    m_saveRequired = False
                    If Not IsNothing(m_UsbCommHandler) AndAlso m_UsbCommHandler.UsbInformation.SerialNo <> "" Then
                        Dim sKey As String = GetRegistryKey(m_UsbCommHandler.UsbInformation.SerialNo, "", "AutoLoad")
                        If sKey = "" Then SetRegistryKey(m_UsbCommHandler.UsbInformation.SerialNo, m_currentFile, "AutoLoad")
                    End If
                    'Catch
                    '    MsgBox("File IO ERROR, Not saved!")
                    '    Err_message(Err.Description)
                    'End Try
                Case "bbd"
                    Dim f_base As New BaseData(m_newCar.ConfigID)
                    m_newCar.SaveCurrent()
                    f_base.setData(m_newCar.getMapRawAsBase(m_newCar.CurrentMapNumber))
                    f_base.setVars(ObjectCopy(m_newCar.getVars))

                    Dim f_memStream As New MemoryStream()
                    Dim serializer As New BinaryFormatter
                    serializer.Serialize(f_memStream, f_base)

                    '------------------------------------------ Compress Object and Encrypt -------------------
                    Dim f_ZipStream As New MemoryStream
                    CompressFile(f_memStream, f_ZipStream, True)
                    Dim f_encStream As New MemoryStream()
                    CryptFile(libStrings.getS(2), f_ZipStream, f_encStream, True)

                    '------------------------------------------ Dump object to file
                    arrayDump(f_encStream.ToArray, saveCar.FileName)
                    f_encStream.Close()
                    f_ZipStream.Close()
                    f_memStream.Close()
                Case Else
                    Err_message("Filename extension not valid")
            End Select
        Else
            Err_message("Save As Operation Cancelled")
        End If
    End Sub
    Private Sub mFopen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFopen.Click

        ''--------------- First check if file already opened and changes are made and need to be saved ------
        Try
            If closeCheckChanges() = False Then Exit Sub
        Catch
        End Try

        ''--------------- Open files as normal --------------------------------------------------------------
        openCar.Title = "Open BikiRom Files"
        openCar.InitialDirectory = Application.StartupPath & "\BikiRom Files"
        openCar.Filter = "BikiR0M files (.bik;.bik2)|*.bik;*.bik2|BikiRom Base Data Template file (.bbd)|*.bbd"

        Dim f_tmp As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        If f_tmp.Tag <> "" Then openCar.FileName = f_tmp.Tag : f_tmp.Tag = "" : GoTo InSideOpen

        If openCar.ShowDialog() = Windows.Forms.DialogResult.OK Then
InSideOpen:
            ' Try
            Dim ext As String = GetExtension(openCar.FileName)

            Dim f_nCar As CarBase = Nothing
            Select Case LCase(ext)
                '---------------------------- Open BikiRom Base Data File ------------------------------------------------------------------
                Case "bbd"
                    reInitialize()
                    f_nCar = openBaseData(openCar.FileName)

                    '----------------------------------- Try Opening Old BikiRom File and IMPORT --------------------------------------------
                Case "bik", "bik2"
                    reInitialize()

                    Dim f_array() As Byte = arrayLoad(openCar.FileName)
                    f_nCar = openCarBase(f_array)
                    If Not IsNothing(f_nCar) Then
                        m_currentFile = openCar.FileName
                        mFsave.Enabled = True
                    Else
                        m_currentFile = openCar.FileName
                        f_nCar = openCarBaseOld(f_array)
                        If Not IsNothing(f_nCar) Then
                            'm_currentFile = openCar.FileName
                            mFsave.Enabled = True
                        Else
                            m_currentFile = ""
                            MsgBox("File format not OK or import failed")
                        End If
                    End If

            End Select

            '--------------------------------------------------------------------------------------------------------------------
            If IsNothing(f_nCar) Then
                reInitialize()
                Err_message("Operation Cancelled Or Failed")
                Exit Sub
            End If
            m_RecentFiles.Add(openCar.FileName)

            m_newCar = f_nCar
            openInitialise()

            'mFsave.Text = "Save " & opencar.FileName.Substring(
            mFsaveAs.Enabled = True
            mfExport.Enabled = True
            mFimport.Enabled = True

            Me.Text = "BikiS0FT - " & m_currentFile
            stFile.Text = GetFileName(m_currentFile)
            'Catch
            '    reInitialize()
            '    Err_report(Err.Description)
            '    Err_message(Err.Description)
            'End Try
        End If

        f_tmp.Tag = ""
    End Sub
    Private Sub mFnew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnFNewFromBase.Click
        openCar.Title = "Open BikiRom Base Data Template File"
        openCar.InitialDirectory = Application.StartupPath & "\Base Data\"
        openCar.Filter = "*.bbd BikiRom Base Data Template file|*.bbd"
        If openCar.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Dim f_car As CarBase = openBaseData(openCar.FileName)
            If Not IsNothing(f_car) Then
                reInitialize()
                m_newCar = f_car
                openInitialise()

                'mFsave.Text = "Save " & opencar.FileName.Substring(
                mFsaveAs.Enabled = True
                mfExport.Enabled = True
                mFimport.Enabled = True

                Me.Text = "BikiS0FT - New File from Template"
                m_currentFile = ""
            Else
                Err_message("File Not valid Template or cancelled")
            End If
        End If
    End Sub
    Private Sub mFexit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFexit.Click
        Me.Close()
    End Sub
    Private Function closeCheckAll() As Boolean
        Try
            Try
                If closeCheckChanges() = False Then Return False
            Catch
                Dim f_question As Integer = MsgBox("Do you want to save the changes you made to:" & Chr(10) & m_currentFile, MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Save Changes")
                Select Case f_question
                    Case MsgBoxResult.Yes
                        dumpBikFile(m_newCar, m_currentFile)
                    Case MsgBoxResult.Cancel
                        Return False
                End Select
            End Try

            ' Operations to Save Settings on Shutdown
            mFexit_SaveSettings()
            m_RecentFiles.UnLoad()
            'Me.Dispose()

            If thread_Check(threadAction.TH_DOWN) Then bwDownload.CancelAsync()
            If thread_Check(threadAction.TH_UPLOAD) Then bwUpload.CancelAsync()
            If thread_Check(threadAction.TH_CONSULT) Then
                bwConsult.CancelAsync()
                Dim delay As UInt32 = 10
                Do
                    Threading.Thread.Sleep(10)
                    delay -= 1
                Loop Until delay = 0 Or Not thread_Check(threadAction.TH_CONSULT)
            End If


            If thread_Check(threadAction.TH_EMUALTOR) Then bwEmulator.CancelAsync()

            ' Clean up the usb thread
            If Not IsNothing(m_UsbCommHandler) Then m_UsbCommHandler.Dispose()

        Catch ex As Exception
        End Try
        Return True
    End Function
    Private Sub mFexit_SaveSettings()
        SetRegistryKey("last_display", m_CurrentDisp)

        My.Settings.Save()
    End Sub
    Private Sub mVglobal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVglobal.Click
        Try
            If Not IsNothing(m_newCar) Then
                GlobalAdd("Map " & m_newCar.CurrentMapNumber + 1 & _
                m_newCar.MapNameFormatted(m_newCar.CurrentMapNumber) & _
                " - " & _
                "Global Variables", _
                m_newCar.CurrentMap, m_newCar.getConfig.getGlobals)
            End If
        Catch
            Err_message("Error getting Global variables")
            Err_report(Err.Description)
        End Try
    End Sub
    Private Sub mFclose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFclose.Click
        Try
            If closeCheckChanges() = False Then Exit Sub
        Catch
        End Try
        If threadsAlive <> threadAction.TH_NONE And threadsAlive <> threadAction.TH_CONSULT Then
            Dim f_q As MsgBoxResult = MsgBox("Background jobs still active, kill all before closing?", MsgBoxStyle.OkCancel + MsgBoxStyle.Information, "Communication/Jobs still in progress")
            Select Case f_q
                Case MsgBoxResult.Ok
                    If thread_Check(threadAction.TH_DOWN) Then bwDownload.CancelAsync()
                    If thread_Check(threadAction.TH_UPLOAD) Then bwUpload.CancelAsync()
                    If thread_Check(threadAction.TH_CONSULT) Then bwConsult.CancelAsync()
                Case MsgBoxResult.Cancel
                    Exit Sub
            End Select
        Else : If thread_Check(threadAction.TH_CONSULT) Then bwConsult.CancelAsync()
        End If
        reInitialize()
        m_newCar = Nothing
    End Sub

    Public Property DisplayByte() As Integer
        Get
            Return m_CurrentDisp
        End Get
        Set(ByVal value As Integer)
            m_CurrentDisp = value
        End Set
    End Property

    Private Sub openInitialise()
        If Not IsNothing(m_newCar) Then
            If Not IsNothing(m_newCar.getConfig) Then
                m_ptArray = m_newCar.CurrentMap
                m_ptTable = m_newCar.getConfig.getTables.getByIndex(0).getByIndex(0)

                If Not IsNothing(m_newCar.getBikSettings) Then
                    If Not IsNothing(m_newCar.getBikSettings.getData) Then m_newCar.getBikSettings.ClearSetting(m_newCar.getVars)
                Else
                    m_newCar.setBikSettings(New BikSettings(m_newCar.getVars))
                End If

                RefreshValidStreamItems()

                'Bind in any newevents
                m_newCar.StreamDB.StreamChangedDelegate = AddressOf uxDataLogging_ChangedCurrent

                menu_Populate(m_newCar)
                Dim preName As String = "Map " & m_newCar.CurrentMapNumber + 1 & _
                m_newCar.MapNameFormatted(m_newCar.CurrentMapNumber)
                Me.GridAdd(m_ptTable, m_ptArray, m_newCar, preName)
                uiUpdate()
                infoPopulate()

                ' start the consult timer!
                If Not IsNothing(Me.m_UsbHandler) AndAlso Me.m_UsbHandler.IsConnected AndAlso Me.m_UsbHandler.Initialised Then
                    tmrConsult.Enabled = True
                    tmrConsult.Start()
                End If
            End If
        End If
    End Sub
    ''' <summary>
    ''' Prompts user to save changes before continuing with other actions
    ''' </summary>
    ''' <returns>Returns False if Cancel is selected</returns>
    ''' <remarks></remarks>
    Private Function closeCheckChanges() As Boolean
        If Not IsNothing(m_newCar) And m_currentFile <> "" Then
            Dim f_crc As New libCRC32
            Dim bSaveRequired As Boolean = False
            If Not m_saveRequired Then
                For i As Integer = 0 To CarBase.MAX_MAPS
                    If Not m_newCar.getVars.getByName("BK_ECU_CRC_MAP" & i) Is Nothing Then
                        If m_newCar.getVars.getByName("BK_ECU_CRC_MAP" & i).Value <> f_crc.GetByteArrayCrc32(m_newCar.getMap(i)) Then
                            bSaveRequired = True
                            Exit For
                        End If
                    End If
                Next
            Else
                bSaveRequired = m_saveRequired
            End If

            If bSaveRequired Then
                Dim f_question As Integer = MsgBox("Save Changes to current file?" & Chr(10) & m_currentFile, MsgBoxStyle.YesNoCancel)
                Select Case f_question
                    Case MsgBoxResult.Yes
                        dumpBikFile(m_newCar, m_currentFile)
                    Case MsgBoxResult.Cancel
                        Return False
                End Select
            End If
        ElseIf m_currentFile = "" And Not IsNothing(m_newCar) Then
            Select Case MsgBox("Save changes to new file?", MsgBoxStyle.Question + MsgBoxStyle.YesNoCancel, "Save Changes")
                Case MsgBoxResult.Yes
                    mFsaveAs.PerformClick()
                    m_currentFile = ""
                Case MsgBoxResult.Cancel
                    Return False
            End Select
        End If
        Return True
    End Function
    Private Function openBaseData(ByVal sInputFile As String) As CarBase
        Dim f_return As CarBase = Nothing
        Try
            Dim f_encStream As New MemoryStream(arrayLoad(sInputFile))
            Dim f_memstream As New MemoryStream()
            Dim Deserializer As New BinaryFormatter

            CryptFile(libStrings.getS(2), f_encStream, f_memstream, False)
            'CryptFile("Who Wants a Body Massge Right now? Or WHAT about later? Oh YE!", f_encStream, f_memstream, False)
            Dim f_outStream As New MemoryStream
            Dim f_mem2Stream As New MemoryStream(f_memstream.ToArray)
            CompressFile(f_mem2Stream, f_outStream, False)

            Dim f_newStream As New MemoryStream(f_outStream.ToArray)
            Dim f_bdata As BaseData = CType(Deserializer.Deserialize(f_newStream), BaseData)
            f_return = f_bdata.getCar()
        Catch
            f_return = Nothing
        End Try
        Return f_return
    End Function
    Private Function openCarBase(ByVal sInputFile As String) As CarBase
        Return openCarBase(arrayLoad(sInputFile))
    End Function
    ''' <summary>
    ''' This function is passed an array containing a Bikirom Car file and will import and pass back a new CarBase class
    ''' </summary>
    ''' <param name="Array">Bikirom Car file array</param>
    ''' <returns>New Imported CarBase</returns>
    ''' <remarks></remarks>
    Private Function openCarBase(ByRef Array() As Byte) As CarBase
        If Array Is Nothing Then Return Nothing

        Dim f_ncar As CarBase
        Dim f_sel As frmCarSelection
        Dim Deserializer As New BinaryFormatter
        ' Try
        ' --------------------------- Try Opening New Encrypted AND comp BikiRom File ----------------------------------
        Dim f_encryptStream As New MemoryStream(Array)
        Dim f_decyptStream As New MemoryStream

        ' ---------------------------- Decrypt Stream and Deflate info a memory stream 
        CryptFile(libStrings.getS(0), f_encryptStream, f_decyptStream, False)
        Dim f_uncomp As New MemoryStream
        Dim f_Comp As New MemoryStream(f_decyptStream.ToArray)
        f_encryptStream.Dispose()
        f_decyptStream.Dispose()
        CompressFile(f_Comp, f_uncomp, False)
        f_Comp.Dispose()

        GC.Collect()

        ' ---------------------------- Deserialise and open!
        'Dim f_memStream As New MemoryStream(f_uncomp)
        f_ncar = CType(Deserializer.Deserialize(f_uncomp), CarBase)
        'f_uncomp.Close()
        f_uncomp.Dispose()
        f_sel = New frmCarSelection(f_ncar)
        f_sel.getConfig()
        If IsNothing(f_ncar.getConfig) Then
            Err_message("Configuration Not Found..")
            If f_sel.ShowDialog() <> Windows.Forms.DialogResult.OK Then
                Err_message("Configuration Not Selected")
                Return Nothing
                Exit Function
            End If
        End If

        f_sel = Nothing
        Return f_ncar
        Exit Function

        Return Nothing
    End Function
    Friend Function openCarBaseOld(ByRef array() As Byte) As CarBase
        Dim f_one() As Byte
        Dim f_two() As Byte
        Dim f_three() As Byte
        Dim f_ncar As CarBase = Nothing
        Dim Deserializer As New BinaryFormatter
        Dim f_nncar As Car = Nothing
        Try
            f_nncar = CType(Deserializer.Deserialize(New MemoryStream(array)), Car)


            openCar.Title = "Open Bikirom Base Data file"
            openCar.InitialDirectory = Application.StartupPath & "\Base Data"
            openCar.Filter = "*.bbd BikiRom Base Data file|*.bbd"
            If openCar.ShowDialog() = Windows.Forms.DialogResult.OK Then
                f_ncar = openBaseData(openCar.FileName)
                If Not IsNothing(f_ncar) And Not IsNothing(f_nncar.mapExport(0)) Then
                    f_one = f_ncar.getMap(0)
                    f_two = f_ncar.getMap(1)
                    f_three = f_ncar.getMap(2)
                    MsgBox("Imported the following; " & Chr(10) & Chr(13) & f_ncar.mapTransfer(f_nncar.mapExport(0), f_one))
                    f_ncar.mapTransfer(f_nncar.mapExport(1), f_two)
                    f_ncar.mapTransfer(f_nncar.mapExport(2), f_three)
                    f_ncar.setMap(f_one, 0)
                    f_ncar.setMap(f_two, 1)
                    f_ncar.setMap(f_three, 2)
                End If
                Return f_ncar
            End If
        Catch
            Return f_ncar
        End Try
        Return Nothing
    End Function
    Friend Function openCarBaseAsOld(ByRef array() As Byte) As Car
        Dim f_ncar As CarBase = Nothing
        Dim Deserializer As New BinaryFormatter
        Dim f_nncar As Car = Nothing
        Try
            f_nncar = CType(Deserializer.Deserialize(New MemoryStream(array)), Car)

            Return f_nncar
        Catch
            Return Nothing
        End Try
        Return Nothing
    End Function
    ''-------------------------------------------------------------------------------------------------------------
    ''---------------------------------------------------------------- UI refresh methods and Event handlers
    Friend Sub uiUpdate()
        If Not IsNothing(m_newCar) Then
            m_ptArray = m_newCar.CurrentMap
            grid_Populate()
            GlobalPopulate()
            menu_Populate(m_newCar)
            tmrGraph.Enabled = False
            tmrGraph.Enabled = True
            If Not IsNothing(m_newCar.getConfig.getBikiVars.getByName("map" & Str(m_newCar.CurrentMapNumber + 1))) Then
                stMap.Text = "Map: " & m_newCar.getConfig.getBikiVars.getByName("map" & Str(m_newCar.CurrentMapNumber + 1)).Description.Description
            Else
                stMap.Text = "Map: " & Str(m_newCar.CurrentMapNumber + 1)
            End If
        End If
    End Sub
    Friend Sub uiReset()
        m_ptArray = m_newCar.CurrentMap
        uiUpdate()
    End Sub
    Friend Sub uiRefresh()
        boxGlobal.Text = m_ptVars.Description
    End Sub

    ''' <summary>
    ''' Generates the Map buttons when the menu opens!... disables all items if there is no current car!
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub mFmaps_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFmaps.DropDownOpening
        Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)

        menuItem.DropDownItems.Clear()
        If Not IsNothing(m_newCar.MapCount) Then

            For i As Integer = 1 To m_newCar.MapCount
                Dim str As String = m_newCar.MapName(i)
                If str <> "" Then str = " (" & str & ")"
                Dim item As New ToolStripMenuItem("Map " & i & str, Nothing, AddressOf mMap1_Click)
                item.Tag = i
                If m_newCar.CurrentMapNumber = i - 1 Then item.Checked = True
                menuItem.DropDownItems.Add(item)
            Next
        End If
    End Sub
    Private Sub mMap1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim f_obj As ToolStripMenuItem = CType(sender, ToolStripMenuItem)

        If f_obj.Tag <> vbNullString Then
            m_newCar.CurrentMapNumber = CInt(f_obj.Tag) - 1
            uiUpdate()
        End If
    End Sub
    Private Sub iBase_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles iBase.Click
        If Not IsNothing(m_newCar) Then
            If iBase.Tag <> "" Then openBin.FileName = iBase.Tag : GoTo skip
            openBin.Title = "Select .bbd BikiRom Base Data file to import"
            openBin.InitialDirectory = Application.StartupPath & "\Base Data\"
            openBin.Filter = "*.bbd Binary|*.bbd"
            If openBin.ShowDialog() = Windows.Forms.DialogResult.OK Then
skip:           Try
                    Dim f_ncar As CarBase = openBaseData(openBin.FileName)
                    If Not IsNothing(f_ncar) Then
                        Dim f_arr() As Byte = f_ncar.baseExport
                        m_newCar.baseImportTransfer(f_arr)
                        'If Not IsNothing(f_arr) Then
                        '    m_newCar.baseImport(f_arr)
                        '    m_newCar.mapTransferAll(m_newCar.getMap(0), f_arr)
                        '    m_newCar.setMap(f_arr, 0)
                        '    m_newCar.mapTransferAll(m_newCar.getMap(1), f_arr)
                        '    m_newCar.setMap(f_arr, 1)
                        '    m_newCar.mapTransferAll(m_newCar.getMap(2), f_arr)
                        '    m_newCar.setMap(f_arr, 2)
                        'End If
                    End If
                    uiReset()
                    Err_message("Base Data imported OK, save and upload to apply")
                Catch ex As Exception
                    Err_message(Err.Description)
                End Try
            Else
                Err_message("Import Base Data Operation Cancelled")
            End If
        End If
        iBase.Tag = ""
    End Sub
    Private Sub iVQ_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim vqMap As Table = m_newCar.getConfig.getTables.getTableByName("vq")
        Dim f_vqBytes() As Byte
        'Try
        If Not IsNothing(vqMap) Then
            openBin.Title = "Select .Bvq/.Vq Volumetric Quantization map file"
            openBin.InitialDirectory = Application.StartupPath & "\VQ Maps\"
            openBin.Filter = "*.vq,*.bvq VQ map|*.bvq;*.vq"
            If openBin.ShowDialog() = Windows.Forms.DialogResult.OK Then

                Dim ext As String = openBin.FileName
                ext = LCase(Mid(ext, Len(ext) - 2, 3))
                Dim f_Avar As BVar = m_newCar.getVars.getByName("afm")
                If ext = ".vq" Then
                    f_vqBytes = arrayLoad(openBin.FileName)
                    For i As Integer = 0 To m_newCar.MapCount - 1
                        vqMap.setRaw(m_newCar.getMap(i), f_vqBytes)
                    Next

                ElseIf ext = "bvq" Then
                    'deserialise the Biki VQ file
                    Dim Deserializer As New BinaryFormatter
                    Dim f_vq As vq = CType(Deserializer.Deserialize(openBin.OpenFile()), vq)

                    For i As Integer = 0 To m_newCar.MapCount - 1
                        vqMap.setRaw(m_newCar.getMap(i), f_vq.Data)
                    Next

                    'Alter K constant for new K value
                    Dim f_Kvar As Var = m_newCar.getConfig.getGlobals.getByName("ISF")

                    If Not IsNothing(f_Kvar) And Not IsNothing(f_Avar) Then
                        f_Avar.Description.Description = f_vq.Name
                        Dim f_Ok As Integer = MsgBox("Do you want to have the K value " & Chr(13) & _
                        "auto adjusted to suite the new AFM?", MsgBoxStyle.OkCancel, "Auto Adjust K constant")
                        If f_Ok = vbOK Then
                            For i As Integer = 0 To m_newCar.MapCount - 1
                                f_Kvar.SetValue(m_newCar.getMap(i), f_Kvar.getValue(m_newCar.getMap(i)) * (f_vq.Value / f_Avar.Value))
                            Next
                        End If
                        f_Avar.Value = (f_vq.Value)
                    End If
                End If
                uiUpdate()
            End If
        Else
            Err_message("Import Vq Operation Cancelled")
        End If
        'Catch ex As Exception
        '   Debug.Print(Err.Description)
        'End Try
    End Sub
    Private Sub iMap_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles iMap.Click
        Dim mapImport() As Byte
        Try
            If Not IsNothing(m_newCar) Then
                openBin.Title = "Select Binary or Bikirom (v1/v2) file to import fuel/ignition/globals etc.."
                openBin.InitialDirectory = Application.StartupPath & "\Base Data\"
                openBin.Filter = "*.bin Binary|*.bin|*.bik BikiRom File|*.bik|*.bik2 BikiRom2 File|*.bik2"
                If iMap.Tag <> "" Then openBin.FileName = iMap.Tag : GoTo skip2
                If openBin.ShowDialog() = Windows.Forms.DialogResult.OK Then
skip2:              mapImport = arrayLoad(openBin.FileName)
                    If GetExtension(openBin.FileName) = "bin" Then
                        If UBound(mapImport) = m_newCar.DataEnd Then
                            Dim f_str As String = m_newCar.mapTransfer(mapImport, m_ptArray)
                            MsgBox("Importing Tables+Vars...;" & Chr(13) & Chr(13) & f_str, MsgBoxStyle.Information)
                        ElseIf UBound(mapImport) = m_newCar.DataEnd - m_newCar.DataStart Then
                            Dim mapImport2(m_newCar.DataEnd) As Byte
                            Array.Copy(mapImport, 0, mapImport2, m_newCar.DataStart, m_newCar.DataEnd - m_newCar.DataStart + 1)
                            Dim f_str As String = m_newCar.mapTransfer(mapImport2, m_ptArray)
                            MsgBox("Importing Tables+Vars...;" & Chr(13) & Chr(13) & f_str, MsgBoxStyle.Information)
                        Else
                            MsgBox("Binary File not the right size or format", MsgBoxStyle.Critical)
                        End If
                    ElseIf GetExtension(openBin.FileName) = "bik" Or GetExtension(openBin.FileName) = "bik2" Then
                        Try
                            Dim objCar As CarBase = openCarBase(mapImport)
                            If Not IsNothing(objCar) Then
                                Dim intMap As Integer = InputBox("Which map do you want to import? [1-3]" & Chr(13) & "This will import over your current map " & m_newCar.CurrentMapNumber + 1, "Import Map", "1")
                                If intMap >= 1 And intMap <= 3 Then
                                    m_newCar.mapTransferAll(objCar.getMap(intMap - 1), m_ptArray)
                                End If
                            Else
                                Dim objCarOld As Car = openCarBaseAsOld(mapImport)
                                Dim intMap As Integer = InputBox("Which map do you want to import? [1-3]" & Chr(13) & "This will import over your current map " & m_newCar.CurrentMapNumber + 1, "Import Map", "1")
                                If intMap >= 1 And intMap <= 3 Then
                                    m_newCar.mapTransfer(objCar.getMap(intMap - 1), m_ptArray)
                                End If
                            End If
                            Err_message("Map data imported, save and upload to apply")
                        Catch
                            Err_message("Invalid Bikirom file")
                        End Try
                    End If
                Else
                    Err_message("Import Map Operation Cancelled")
                End If
            End If
        Catch ex As Exception
        Finally
            iMap.Tag = ""
            uiUpdate()
        End Try
    End Sub

    Private Sub mFile_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuFile.DropDownOpening
        If Not IsNothing(m_newCar) Then
            Dim f_var As BVar
            f_var = m_newCar.getVars.getByName("map1")
            If Not IsNothing(f_var) Then mMap1.Text = "Map 1 - " & f_var.Description.Description Else mMap1.Text = "Map 1"
            f_var = m_newCar.getVars.getByName("map2")
            If Not IsNothing(f_var) Then mMap2.Text = "Map 2 - " & f_var.Description.Description Else mMap2.Text = "Map 2"
            f_var = m_newCar.getVars.getByName("map3")
            If Not IsNothing(f_var) Then mMap3.Text = "Map 3 - " & f_var.Description.Description Else mMap3.Text = "Map 3"
            mFclose.Enabled = True
            mFmaps.Enabled = True
            mFsaveAs.Enabled = True
            mFimport.Enabled = True
            If m_currentFile <> "" Then mFsave.Enabled = True Else mFsave.Enabled = False
        Else
            mFclose.Enabled = False
            mFmaps.Enabled = False
            mFsave.Enabled = False
            mFsaveAs.Enabled = False
            mFimport.Enabled = False
        End If
    End Sub
    Private Sub mEdit_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuEdit.DropDownOpening
        mFileCopyTo.DropDownItems.Clear()
        Dim f_mnuItem(0) As ToolStripMenuItem
        If Not IsNothing(m_newCar) Then
            For i As Integer = 1 To m_newCar.MapCount
                If m_newCar.CurrentMapNumber <> i - 1 Then
                    If IsNothing(m_newCar.getVars.getByName("map" & i)) Then
                        Dim item As New ToolStripMenuItem("Map " & i, Nothing, AddressOf mFileCopyToItem_Click)
                        item.Tag = i - 1
                        mFileCopyTo.DropDownItems.Add(item)
                    End If
                End If
            Next
        End If
    End Sub
    Private Sub mFileCopyToItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim f_obj As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        m_newCar.mapTransferAll(m_newCar.CurrentMap, m_newCar.getMap(Val(f_obj.Tag)))
    End Sub
    Private Sub uxMenuEditMapName_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuEditMapName.Click
        If Not IsNothing(m_newCar) Then
            Dim str As String = m_newCar.MapName(m_newCar.CurrentMapNumber + 1)
            If str <> "" Then str = " (" & str & ")"

            ' Generate the question
            Dim question As New frmBDialog("Enter the name for this ECU Map " & m_newCar.CurrentMapNumber + 1 & str & Chr(13) & _
                                            "Leave blank to clear the current name", "ECU Map Name Change", m_newCar.MapName(m_newCar.CurrentMapNumber + 1))

            ' Truncate to 64 characters
            If question.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso question.Value <> "" Then
                str = question.Value
                If question.Value.Length > 64 Then
                    str = str.Substring(0, 64)
                End If
                m_newCar.MapName(m_newCar.CurrentMapNumber + 1) = str
            End If
        End If
    End Sub

#End Region

#Region "-------------------------------- Display/Control -= Bikirom Info and Inj/Afm swap"
    Private Sub cmdChangeConfig_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdChangeConfig.Click
        Dim f_formSelect As New frmCarSelection(m_newCar)
        If f_formSelect.ShowDialog() = Windows.Forms.DialogResult.OK Then
            openInitialise()
        End If
    End Sub
    ''' <summary>
    ''' Popualtes the Group Box "Car Info/Configuartion" with infomation from the current opened file
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub infoPopulate()
        If Not IsNothing(m_newCar) Then
            If Not IsNothing(m_newCar.getConfig) Then
                With m_newCar.getVars
                    dgInfo.Rows.Clear()
                    dgInfo.Tag = m_newCar.getVars

                    tbEngine.Text = m_newCar.getConfig.Engine
                    tbSeries.Text = m_newCar.getConfig.Series

                    Dim f_inj As BVar = .getByName("INJ")
                    Dim f_afm As BVar = .getByName("AFM")
                    If Not IsNothing(f_inj) Then tbInjectors.Text = f_inj.Description.Description Else tbInjectors.Text = "Not Set"
                    If Not IsNothing(f_afm) Then tbAfm.Text = f_afm.Value & " " & f_afm.Description.Description Else tbAfm.Text = "Not Set"

                    Dim f_count As Int16 = 0
                    For Each row As BVar In .getAsArray
                        Select Case LCase(row.Name)
                            Case "note"
                                dgInfo.RowCount += 1
                                dgInfo.Item(0, f_count).Value = row.Description.Description
                                dgInfo.Item(0, f_count).ReadOnly = True
                                'dgInfo.Item(0, f_count).Tag = row
                                If dgInfo.Item(0, f_count).Value.ToString.Length >= 60 Then dgInfo.Rows(f_count).Height *= dgInfo.Item(0, f_count).Value.ToString.Length \ 60
                                dgInfo.Item(0, f_count).ToolTipText = "Dbl Click to edit"
                                f_count += 1
                            Case "kmult"
                                dgInfo.RowCount += 1
                                dgInfo.Item(0, f_count).Value = row.Value
                                dgInfo.Item(0, f_count).ReadOnly = True
                                dgInfo.Item(0, f_count).ToolTipText = row.Description.Description & " - Dbl click to edit"
                                f_count += 1
                        End Select
                    Next
                    If dgInfo.RowCount >= 1 Then dgInfo.Item(0, dgInfo.RowCount - 1).ToolTipText = "Dbl Click To Add new Note"
                    Try
                        Dim di As New IO.DirectoryInfo(Application.StartupPath & "\VQ Maps\")
                        Dim diar1 As IO.FileInfo() = di.GetFiles()
                        Dim dra As IO.FileInfo
                        Dim f_list(diar1.Length - 1) As vq
                        f_count = 0
                        'list the names of all files in the specified directory
                        Dim Deserializer As New BinaryFormatter
                        cbAfm.Items.Clear()
                        For Each dra In diar1
                            If dra.Extension = ".bvq" Then
                                Dim f_io As IO.FileStream = dra.Open(FileMode.Open, FileAccess.Read)
                                Dim f_vq As vq = CType(Deserializer.Deserialize(f_io), vq)
                                f_io.Close()
                                f_list(f_count) = f_vq
                                cbAfm.Items.Add(New String(f_vq.Name))
                                f_count += 1
                            End If
                        Next
                        ReDim Preserve f_list(f_count - 1)
                        cbAfm.Tag = f_list
                    Catch
                        Err_message("Error Loading AFM Info")
                    End Try

                    cbInjectors.Items.Clear()
                    Dim f_injs() As Injectors = New Injectors() { _
                        New Injectors("cc S/N13,14,15 sr20de", 257), New Injectors("cc U/S13,14,S14a sr20det", 386), _
                        New Injectors("cc s15/rnn14 sr20det", 440), New Injectors("cc generic", 550), New Injectors("cc generic", 660), _
                        New Injectors("cc generic", 740), New Injectors("cc generic", 850), New Injectors("cc generic", 1000)}
                    For Each inj As Injectors In f_injs
                        cbInjectors.Items.Add(New String(inj.Value & inj.Name))
                    Next
                    cbInjectors.Tag = f_injs

                End With
            End If
        End If
    End Sub
    Private Sub dgInfo_CellDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgInfo.CellDoubleClick
        Dim f_grid As DataGridView = CType(sender, DataGridView)
        If e.RowIndex = f_grid.RowCount - 1 Then
            m_newCar.getVars.addNode(New BVar("note", New BikDescription("Blank note... EDIT ME!")))
            infoPopulate()
        Else
            f_grid.Item(e.ColumnIndex, e.RowIndex).ReadOnly = False
        End If
    End Sub
    Private Sub dgInfo_CellEndEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgInfo.CellEndEdit
        Dim f_grid As DataGridView = CType(sender, DataGridView)
        Try
            If f_grid.Item(e.ColumnIndex, e.RowIndex).ReadOnly = False Then
                Dim f_count As Int16 = 0
                For Each row As BVar In m_newCar.getVars.getAsArray
                    If LCase(row.Name) = "note" Or LCase(row.Name) = "kmult" Then
                        f_count += 1
                    End If
                    If e.RowIndex = f_count - 1 Then
                        If LCase(row.Name) = "note" Then
                            Debug.Print("desc set " & row.Name)
                            row.Description = New BikDescription(dgInfo.Item(0, e.RowIndex).Value.ToString)
                            f_grid.Item(e.ColumnIndex, e.RowIndex).ReadOnly = True
                        Else
                            row.Value = Val(dgInfo.Item(0, e.RowIndex).Value)
                        End If
                    End If
                Next
            End If
            m_saveRequired = True
        Catch
        End Try
    End Sub
    Private Sub dgInfo_UserAddedRow(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgInfo.UserAddedRow
        Dim f_grid As DataGridView = CType(sender, DataGridView)
        Try
            If Not IsNothing(f_grid.Tag) Then
                Dim t_tag As BVars = CType(f_grid.Tag, BVars)
                m_newCar.getVars.addNode(New BVar("info", New BikDescription(e.Row.Cells(0).Value)))
            End If
        Catch ex As Exception
        Finally
            infoPopulate()
            Debug.Print("Repopulate info")
        End Try
    End Sub
    Private Sub cmdApplyAfm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApplyAfm.Click
        If Not IsNothing(m_newCar) Then
            If Not IsNothing(m_newCar.getConfig) Then
                Dim f_bvq As vq = Nothing
                Dim f_vqTable As Table = m_newCar.getConfig.getTables.getTableByName("Sensor - VQ Table")

                If Not IsNothing(f_vqTable) Then
                    If cbAfm.SelectedIndex >= 0 Then
                        f_bvq = CType(cbAfm.Tag, vq())(cbAfm.SelectedIndex)
                    ElseIf IsNumeric(cbAfm.Text) Then
                        f_bvq = New vq(f_vqTable.getRaw(m_newCar.Map(0)), cbAfm.Text, "ps Custom Afm")
                    End If

                    Dim f_ISF As Var = m_newCar.getConfig.getGlobals.getByName("ISF")
                    Dim f_afm As BVar = m_newCar.getVars.getByName("AFM")

                    If Not IsNothing(f_bvq) Then
                        If Not IsNothing(f_vqTable) And IsNothing(f_ISF) Then
                            '' Set or do nothing?
                            If MsgBox("Set VQ table for;" & Chr(13) & cbAfm.SelectedValue & Chr(13) & "ISF auto-set Not possible", MsgBoxStyle.Information + MsgBoxStyle.YesNo, "Auto-Set Not possible") = MsgBoxResult.Yes Then
                                ' Set VQ table
                                For i As Integer = 0 To m_newCar.MapCount - 1
                                    f_vqTable.setRaw(m_newCar.Map(i), f_bvq.Data)
                                Next
                            End If
                        ElseIf IsNothing(f_vqTable) Or IsNothing(f_ISF) Then
                            MsgBox("Importing of VQ table and ISF not possible" & Chr(13) & "Configuation error or limitation", MsgBoxStyle.Critical, "Auto-Set Not possible")
                        Else
                            If MsgBox("Set VQ table for;" & Chr(13) & cbAfm.SelectedValue, MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Set VQ table?") = MsgBoxResult.Yes Then
                                For i As Integer = 0 To m_newCar.MapCount - 1
                                    f_vqTable.setRaw(m_newCar.Map(i), f_bvq.Data)
                                Next
                            End If
                            If MsgBox("Auto set the ISF to compensate " & Chr(13) & "for different sizes afm?", MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Auto-Set ISF Variable") = MsgBoxResult.Yes Then
                                For i As Integer = 0 To m_newCar.MapCount - 1
                                    f_ISF.SetValue(m_newCar.Map(i), f_ISF.getValue(m_newCar.Map(i)) * (f_bvq.Value / f_afm.Value))
                                Next
                            End If
                        End If

                        If Not IsNothing(f_afm) Then
                            f_afm.Value = f_bvq.Value
                            f_afm.Description.Description = f_bvq.Name
                        Else
                            m_newCar.getVars.addNode(New BVar("AFM", New BikDescription(f_bvq.Name), f_bvq.Value))
                        End If
                    End If
                    m_saveRequired = True
                Else
                    Err_message("Error: Cannot find VQ Table, Config Error")
                End If
            End If
        End If
        infoPopulate()
        uiUpdate()
    End Sub
    Private Sub cmdApplyInjectors_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApplyInjectors.Click
        If Not IsNothing(m_newCar) Then
            If Not IsNothing(m_newCar.getConfig) Then
                Dim f_inj As Injectors
                If cbInjectors.SelectedIndex >= 0 Then
                    f_inj = CType(cbInjectors.Tag, Injectors())(cbInjectors.SelectedIndex)
                Else
                    If IsNumeric(cbInjectors.Text) Then
                        f_inj = New Injectors("cc Custom Size", Val(cbInjectors.Text))
                    Else
                        f_inj = Nothing
                        Err_message("Error: Numeric values required in CC")
                    End If
                End If

                If Not IsNothing(f_inj) Then
                    Dim f_OldInj As BVar = m_newCar.getVars.getByName("INJ")
                    Dim f_ISF As Var = m_newCar.getConfig.getGlobals.getByName("ISF")

                    If Not IsNothing(f_inj) And Not IsNothing(f_ISF) And Not IsNothing(f_OldInj) Then
                        If MsgBox("Auto set the ISF to compensate " & Chr(13) _
                           & "for different sized Injectors?" & Chr(13) _
                           & "Old: " & f_OldInj.Value & " vs New: " & f_inj.Value, MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Auto-Set ISF Variable") = MsgBoxResult.Yes _
                        Then
                            For i As Integer = 0 To m_newCar.MapCount - 1
                                f_ISF.SetValue(m_newCar.Map(i), f_ISF.getValue(m_newCar.Map(i)) * (f_OldInj.Value / f_inj.Value))
                            Next


                        End If
                        If MsgBox("Auto set the load scales" & Chr(10) _
                           & "for the different sized Injecotrs?" & Chr(10) _
                           & "Old: " & f_OldInj.Value & " vs New: " & f_inj.Value, MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Auto-Set Load Scales") = MsgBoxResult.Yes _
                        Then
                            Dim fArray As New ArrayList
                            For Each tab As Table In m_newCar.getConfig.getTables.getTablesAsArray
                                If Not IsNothing(tab.getWidthScale) AndAlso Not fArray.Contains(tab.getWidthScale.Address) Then
                                    If scaleCheckIfLoad(tab.getWidthScale, f_OldInj.Value / CDbl(f_inj.Value), tab.Width) Then
                                        fArray.Add(tab.getWidthScale.Address)
                                    End If
                                End If
                                If Not IsNothing(tab.getHeightScale) AndAlso Not fArray.Contains(tab.getHeightScale.Address) Then
                                    If scaleCheckIfLoad(tab.getHeightScale, f_OldInj.Value / CDbl(f_inj.Value), tab.Height) Then
                                        fArray.Add(tab.getHeightScale.Address)
                                    End If
                                End If
                            Next
                        End If
                    Else
                        MsgBox("Auto set of ISF not possible, Configuration Error", MsgBoxStyle.Information, "Auto set not possible")
                    End If
                    m_saveRequired = True
                    f_OldInj.Value = f_inj.Value
                    f_OldInj.Description.Description = f_inj.Value & f_inj.Name
                    uiUpdate()
                    infoPopulate()
                End If
            End If
        End If
    End Sub
    ''' <summary>
    ''' Takes a scale, checks if its a load scale and then applies the given multiplier to the scale
    ''' </summary>
    ''' <param name="iScale"></param>
    ''' <param name="Multi"></param>
    ''' <remarks></remarks>
    Private Function scaleCheckIfLoad(ByRef iScale As Scale, ByVal Multi As Double, ByVal length As Integer) As Boolean
        If iScale.Trace = traceScheme.TRC_LOAD Or iScale.Trace = traceScheme.TRC_TP And iScale.Address >= 0 Then
            For i As Integer = 0 To m_newCar.MapCount - 1
                iScale.MultiplyValues(m_newCar.Map(i), Multi, length)
            Next
            Return True
        Else
            Return False
        End If
    End Function

    Private Sub EcuInfoConfigToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVECUInfo.Click
        Me.uxBarInfo.Show(Me.uxDockingPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document)
    End Sub
#End Region

#Region "-------------------------------- Stream Recieving Function/Events"
    Private Sub DisplayMessageHandler(ByVal sender As Object, ByVal e As DataStream.DisplayMessageEventArgs)
        Err_message(e.Message, e.Severity)
    End Sub
    Private Sub InitialiseFormStreamControls()
        ' Add all the standard controls to the container
        InitialiseStreamControl(uxBarContainerTop)
        InitialiseStreamControl(Me.gSPEED)
        InitialiseStreamControl(Me.gRPM)
        InitialiseStreamControl(Me.uxGraphOne)
        'InitialiseStreamControl(Me.dGrid)

        ' Refresh all the valid stream items
        RefreshValidStreamItems()

    End Sub
    Private Sub InitialiseStreamControl(ByVal Control As Object)
        If Not m_StreamControls.Contains(Control) Then
            m_StreamControls.Add(Control)
            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamRecieve).FullName, True) Is Nothing Then
                Dim StreamRecieve As DataStream.IStreamRecieve = CType(Control, DataStream.IStreamRecieve)
                AddHandler StreamRecieve.Seek, AddressOf Me.Stream_Seek
                AddHandler StreamRecieve.Restrict, AddressOf Me.Stream_Restrict
                AddHandler StreamRecieve.RequestRefresh, AddressOf Me.Stream_RequestRefresh
                AddHandler StreamRecieve.Close, AddressOf Me.Stream_Close
            End If

            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamRuntime).FullName, True) Is Nothing Then
                Dim RunTime As DataStream.IStreamRuntime = CType(Control, DataStream.IStreamRuntime)
                If Not IsNothing(RunTime.MenuItems) Then
                    uxMenuExtensions.DropDownItems.AddRange(RunTime.MenuItems)
                End If
            End If

            ' Apply setting if possible
            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing _
            AndAlso Me.m_UserDesktopSettings.CurrentDesktop.StreamControlSettings.Contains(CType(Control, INamed).Name) Then
                Me.m_UserDesktopSettings.CurrentDesktop.StreamControlSettings(CType(Control, INamed).Name).ApplySettings(Control)
            End If

            ' Add the Control to the form
            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamControl).FullName, True) Is Nothing Then
                Dim IControl As DataStream.IStreamControl = Control
                Dim Container As New WeifenLuo.WinFormsUI.Docking.DockContent()
                Container.Controls.Add(IControl)
                Container.Show(Me.uxDockingPanel, IControl.ControlLocation)
            End If
        End If
    End Sub
    Private Sub UnInitialiseStreamControl(ByVal Control As Object)
        If m_StreamControls.Remove(Control) Then
            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamRecieve).FullName, True) Is Nothing Then
                Dim StreamRecieve As DataStream.IStreamRecieve = CType(Control, DataStream.IStreamRecieve)
                RemoveHandler StreamRecieve.Seek, AddressOf Me.Stream_Seek
                RemoveHandler StreamRecieve.Restrict, AddressOf Me.Stream_Restrict
                RemoveHandler StreamRecieve.RequestRefresh, AddressOf Me.Stream_RequestRefresh
                RemoveHandler StreamRecieve.Close, AddressOf Me.Stream_Close
            End If

            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamRuntime).FullName, True) Is Nothing Then
                Dim RunTime As DataStream.IStreamRuntime = CType(Control, DataStream.IStreamRuntime)
                If Not IsNothing(RunTime.MenuItems) Then
                    For Each item As ToolStripMenuItem In RunTime.MenuItems
                        uxMenuExtensions.DropDownItems.RemoveByKey(item.Name)
                    Next
                End If
            End If

            ' Save the current settings
            If Not Control.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing Then
                Dim settings As UI.UserDesktopSettings = Me.m_UserDesktopSettings.CurrentDesktop
                Dim setting As UI.UserStreamControlSettings
                If settings.StreamControlSettings.Contains(Control.Name) Then
                    ' Save to current
                    setting = settings.StreamControlSettings(Control.Name)
                Else
                    ' Create new
                    setting = New UI.UserStreamControlSettings(Control.Name)
                    settings.StreamControlSettings.Add(setting)
                End If
                ' Save the actual setting
                setting.SaveSetting(Control)
            End If

        End If
    End Sub

    ''' <summary>
    ''' Refreshes all the controls with the valid stream items
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub RefreshValidStreamItems()
        Dim ValidItems As String() = My.Settings.validStreamItemNames.Split("|")

        ' Check out the current stream and add this to the valid stream item names
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then
            Dim CurrentValids As ObjectModel.Collection(Of String) = m_newCar.StreamDB.CurrentStream.ValidItems
            ReDim Preserve ValidItems(ValidItems.Length + CurrentValids.Count - 1)
            For i As Integer = 0 To CurrentValids.Count - 1
                ValidItems(ValidItems.Length - CurrentValids.Count + i) = CurrentValids(i)
            Next
        End If

        Dim control As DataStream.IStreamConfig = Nothing
        If My.Settings.validStreamItemNames.Length > 0 Then
            For Each obj As Object In m_StreamControls
                If Not obj.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing Then
                    control = CType(obj, DataStream.IStreamConfig)
                    control.InitialiseValidItems(ValidItems)
                End If
            Next
        End If
        If My.Settings.validUserStreamItemNames.Length > 0 Then
            For Each obj As Object In m_StreamControls
                If Not obj.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing Then
                    control = CType(obj, DataStream.IStreamConfig)
                    control.InitialiseValidItems(ValidItems)
                End If
            Next
        End If

        ' Assign any relevant registered fields
        Dim Handler As DataStream.IStreamHandle = Nothing
        For Each obj As Object In m_StreamControls
            If Not obj.GetType.GetInterface(GetType(DataStream.IStreamHandle).FullName, True) Is Nothing Then
                Handler = CType(obj, DataStream.IStreamHandle)
                Handler.GetCurrentStreamLog = AddressOf GetCurrentStreamLog
            End If
        Next
    End Sub

    Private Function GetCurrentStreamLog() As DataStream.StreamLog
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then
            Return m_newCar.StreamDB.CurrentStream
        Else
            Return Nothing
        End If
    End Function

    ''' <summary>
    ''' Handles Form Mains implemenetation of the Recieve Stream Function
    ''' </summary>
    ''' <param name="Stream"></param>
    ''' <remarks></remarks>
    Public Sub RecieveStream(ByVal Stream As DataStream.Stream) Implements DataStream.IStreamRecieve.RecieveStream
        If Me.IsDisposed Then Return
        Dim str As DataStream.IStreamRecieve
        ' Send the data to all items!
        ' Do all producers first
        For Each obj As Object In m_StreamControls
            If Not obj.GetType().GetInterface(GetType(DataStream.IStreamRecieve).FullName, True) Is Nothing Then
                str = obj

                If str.RecieverType = DataStream.StreamRecieveType.eStreamProducer Then
                    str.RecieveStream(Stream)
                End If
            End If
        Next

        ' Perform update if required
        If m_newCar.StreamDB.CurrentStream.ValidItems.Count < Stream.Count Then
            m_newCar.StreamDB.CurrentStream.ValidItemsRefresh()
        End If

        ' then do the consumers
        For Each obj As Object In m_StreamControls
            If Not obj.GetType().GetInterface(GetType(DataStream.IStreamRecieve).FullName, True) Is Nothing Then
                str = obj

                If str.RecieverType = DataStream.StreamRecieveType.eStreamConsumeOnly Then
                    str.RecieveStream(Stream)
                End If
            End If
        Next
    End Sub

    ''' <summary>
    ''' Causes the stream to Seek and calls a Refresh on all controls
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Stream_Seek(ByVal sender As Object, ByVal e As DataStream.StreamSeekEventArgs) Handles Me.Seek
        If Not IsNothing(Me.m_newCar.StreamDB.CurrentStream) _
        AndAlso Me.m_newCar.StreamDB.CurrentStream.Count > e.Index And e.Index > 0 Then
            Dim stream As DataStream.Stream = Me.m_newCar.StreamDB.CurrentStream(e.Index)
            ' Send the data to all items!
            For Each obj As Object In m_StreamControls
                If Not obj.GetType().GetInterface(GetType(DataStream.IStreamRecieve).FullName, True) Is Nothing Then
                    CType(obj, DataStream.IStreamRecieve).RecieveSeek(stream)
                End If
            Next
        End If
    End Sub

    ''' <summary>
    ''' Causes the stream to be restricted to a certain area. This will cause some controls
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Stream_Restrict(ByVal sender As Object, ByVal e As DataStream.StreamRestrictEventArgs)
        Dim streamLog As DataStream.StreamLog = Me.m_newCar.StreamDB.CurrentStream

        If Not IsNothing(streamLog) Then
            streamLog.RestrictStart = e.StartIndex
            streamLog.RestrictEnd = e.EndIndex
        End If
    End Sub

    ''' <summary>
    ''' Causes the stream control to be removed from the queue
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Stream_Close(ByVal sender As Object, ByVal e As System.EventArgs)
        UnInitialiseStreamControl(sender)
    End Sub

    ''' <summary>
    ''' Causes the control raising the event to be refreshed with a new stream
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Stream_RequestRefresh(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim control As DataStream.IStreamRecieve = CType(sender, DataStream.IStreamRecieve)
        control.RecieveStream(m_newCar.StreamDB.CurrentStream.CurrentItem)
    End Sub

    Public Event RequestRefresh(ByVal sender As Object, ByVal e As System.EventArgs) Implements DataStream.IStreamRecieve.RequestRefresh

    Public Event Restrict(ByVal sender As Object, ByVal e As DataStream.StreamRestrictEventArgs) Implements DataStream.IStreamRecieve.Restrict

    Public Event Seek(ByVal sender As Object, ByVal e As DataStream.StreamSeekEventArgs) Implements DataStream.IStreamRecieve.Seek
#End Region

#Region "-------------------------------- Thread -= Datalogging"

    Private Sub DataloggingToolStripMenuItem_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuDatalogging.DropDownOpening
        menu_DataLoggingPopulate()

        If Not IsNothing(Me.m_UsbHandler) AndAlso Me.m_UsbHandler.UsbInformation.BoardVersion >= Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV3 Then
            mVDEraseDatalogs.Enabled = True
            mVDDownloadDatalogs.Enabled = True
        Else
            mVDEraseDatalogs.Enabled = False
            mVDDownloadDatalogs.Enabled = False
        End If
    End Sub

    Private Sub mVDDownloadDatalogs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVDDownloadDatalogs.Click
        Dim downloader As New Threads.TH_DataLogging(Me.m_UsbHandler, 2)

        ' create the progrss form
        Dim frm As New frmProgress("Downloading Datalog(s) from Bikirom", New EventHandler(AddressOf bwDatalog_CancelButton_Click))

        ' add item to queue
        m_cmdQueue.Enqueue(New Threads.QueueObj(downloader, threadAction.TH_DATALOG, BikiAction.BK_NONE, frm))

        ' Nudge
        thread_nudge()

    End Sub

    Private Sub mVDEraseDatalogs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVDEraseDatalogs.Click
        If thread_CheckIfOK(threadAction.TH_ERASEDATALOGS) Then
            thread_Add(threadAction.TH_ERASEDATALOGS)
            Dim iQuestion As Integer = MsgBox("Are you sure you want to erase all datalogs on your BikiRom?", MsgBoxStyle.OkCancel, "Erase DataLogs?")
            If iQuestion = vbOK Then

                If BikiRom_Init() = BK_return.BK_OK Then
                    Err_message("Erasing............")
                    Dim frame As Comm.Comm_Frame
                    Dim dts As Date = Date.Parse("1/1/2008")

                    m_UsbCommHandler.Timeout = 4000

                    frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, 0, Comm.Comm_Frame.BikiFrameAction.eCmdRunDataLogging, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                    If m_UsbCommHandler.SendFrame(frame, Nothing, True) = Comm.Comm_Frame.BikiFrameResponse.CMD_OK Then
                        Threading.Thread.Sleep(100)

                        frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, CUInt(Now.Subtract(dts).TotalSeconds), Comm.Comm_Frame.BikiFrameAction.eCmdRunDataLogErase, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                        If m_UsbCommHandler.SendFrame(frame, Nothing, True, 2) = Comm.Comm_Frame.BikiFrameResponse.CMD_OK Then
                            Err_message("DataLog(s) Erased")
                        Else
                            Err_message("DataLog(s) Not Erased, Firmware/BikiSoft upgrade required")
                        End If
                    Else
                        Err_message("Unable to stop datalogging to erase datalog(s)", message_type.MSG_Error)
                    End If
                Else
                    Err_message("Error: Erase Failed")
                End If
            End If
            thread_Remove(threadAction.TH_ERASEDATALOGS)
        Else
            If thread_Check(threadAction.TH_CONSULT) Then consultClose()
            m_cmdQueue.Enqueue(New Threads.QueueObj(Nothing, threadAction.TH_ERASEDATALOGS, BikiAction.BK_NONE, Nothing))
        End If
    End Sub

    ''' <summary>
    ''' Adds the data log to the logging database
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub DataLogging_NotifyEvent(ByVal sender As Object, ByVal e As Threads.DataLoggingEventArgs)
        If Not IsNothing(Me.m_newCar) AndAlso Not IsNothing(Me.m_newCar.StreamDB) Then
            Me.m_newCar.StreamDB.Add(e.DataLog)
        End If
    End Sub
    Private Sub bwDatalog_CancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        If bwDatalog.IsBusy Then
            bwDatalog.CancelAsync()
        End If
    End Sub
    Private Sub EventBikiProgressDatalog( _
       ByVal sender As Object, ByVal e As Threads.BikiThread_Args)
        bwDatalog.ReportProgress(e.Progress, e)
    End Sub
    Private Sub bwDatalog_ProgressChanges( _
            ByVal sender As Object, _
            ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwDatalog.ProgressChanged
        Dim state As Threads.BikiThread_Args = CType(e.UserState, Threads.BikiThread_Args)

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.SetProgress(state.Progress)
            m_cmdCurrent.m_ProgressForm.AddMessage(state.Message)
        Else
            StatusPercent(state.Progress)
            Err_message(state.Message)
        End If

    End Sub
    Private Sub bwDatalog_RunWorkerCompleted( _
            ByVal sender As Object, _
            ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwDatalog.RunWorkerCompleted
        On Error Resume Next
        Dim frmDisp As frmInformation
        ' Check the Error property before checking the Cancelled property:
        If e.Error IsNot Nothing Then
            Err_message(e.Error.Message)
        ElseIf e.Cancelled Then
            Err_message("Download cancelled")
        End If

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.Close()
        End If

        Select Case CType(e.Result, Threads.MultiVersionThread.thread_result)
            Case Threads.MultiVersionThread.thread_result.rslt_allok_reset_required
                Err_message("Download Complete")
                frmDisp = New frmInformation("ECU Reset", "Following the Uploading/Downloading for MAP Data to V1/V2 Bikirom Boards, an ECU reset maybe required", , MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_allok
                Err_message("Download Complete")
            Case Threads.MultiVersionThread.thread_result.rslt_bikisoft_error
                frmDisp = New frmInformation("BikiSoft Error", "A Serious error was encountered that should have been handled internaly, " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_board_fault
                frmDisp = New frmInformation("BikiRom USB Board Error", "A Potential Board fault was detected, Or an extreme communication ropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_comms_error
                frmDisp = New frmInformation("BikiRom USB Communication Error", "A Communication dropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                frmDisp.ShowDialog()
        End Select

        thread_Remove(threadAction.TH_DATALOG)
        thread_PendingDo()

    End Sub
    Private Sub bwDatalog_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwDatalog.DoWork
        Dim ul As Threads.TH_DataLogging = CType(e.Argument, Threads.TH_DataLogging)
        AddHandler ul.Progress, AddressOf EventBikiProgressDatalog
        AddHandler ul.Message, AddressOf EventBikiProgressDatalog
        AddHandler ul.RecieveDatalog, AddressOf DataLogging_NotifyEvent

        ul.Execute(bwDatalog, e)
    End Sub

#End Region

#Region "-------------------------------- Thread -= Uploading"
    Private Function arrayPad(ByRef array() As Byte, ByVal PadOrDePad As Boolean) As Byte()
        Dim f_return() As Byte = Nothing
        If PadOrDePad Then
            ReDim f_return(0 To (array.GetLength(0) * 2) - 1)
            For i As Integer = 0 To array.GetUpperBound(0)
                f_return(i * 2) = array(i)
                f_return((i * 2) + 1) = array(i)
            Next
        Else
            ReDim f_return(0 To (array.GetLength(0) \ 2) - 1)
            For i As Integer = 0 To UBound(f_return)
                f_return(i) = array(i * 2)
            Next
        End If
        Return f_return
    End Function

    Private Function Bikirom_ConfirmConnect() As Boolean
retry:
        Dim f_ret As BK_return = BikiRom_Init()
        If f_ret <> BK_return.BK_OK Then
            errDisplay(f_ret)
            BikiRom_Reset()
            Dim f_return As Integer = MsgBox("Error Connecting to the BikiRom USB board. " & Chr(13) _
            & "Please check that your ignition is turned ON" & Chr(13) _
            & "and USB cable is plugged in..", MsgBoxStyle.Critical + MsgBoxStyle.OkCancel, "Error Connecting")
            If f_return = vbOK Then GoTo retry Else Return False
        Else
            Return True
        End If
    End Function
    Private Function bUploadData(ByVal Action As BikiAction) As TH_BikiRom_Up

        Dim ul As TH_BikiRom_Up = Nothing

        ul = New TH_BikiRom_Up(Me.m_UsbHandler, m_newCar, Action)

        Return ul
    End Function
    Private Sub bwUpload_InitialiseUpload(ByVal Action As BikiAction)
        ' create the progrss form
        Dim frm As New frmProgress("Uploading to Bikirom", New EventHandler(AddressOf bwUpload_CancelButton_Click))

        ' add item to queue
        m_cmdQueue.Enqueue(New Threads.QueueObj(bUploadData(Action), threadAction.TH_UPLOAD, Action, frm))

        ' Nudge
        thread_nudge()
    End Sub
    Private Sub bUploadAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mBSBupload.Click
        bwUpload_InitialiseUpload(BikiAction.BK_EVERYTHING)
    End Sub
    Private Sub EventBikiProgressUp( _
       ByVal sender As Object, ByVal e As Threads.BikiThread_Args)

        ' A file was found. Report the progress, triggering the
        ' BackgroundWorker.ProgressChanged event:
        'Dim intPercent As Integer = e.Progress
        'If intPercent >= 100 Then
        '    intPercent = 100
        'ElseIf intPercent < 0 Then
        '    intPercent = 0
        'End If
        bwUpload.ReportProgress(e.Progress, e)
    End Sub
    Private Sub bwUpload_ProgressChanges( _
            ByVal sender As Object, _
            ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwUpload.ProgressChanged
        Dim state As Threads.BikiThread_Args = CType(e.UserState, Threads.BikiThread_Args)

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.SetProgress(state.Progress)
            m_cmdCurrent.m_ProgressForm.AddMessage(state.Message)
        Else
            StatusPercent(state.Progress)
            Err_message(state.Message)
        End If

    End Sub
    Private Sub bwUpload_RunWorkerCompleted( _
            ByVal sender As Object, _
            ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwUpload.RunWorkerCompleted
        On Error Resume Next
        Dim frmDisp As frmInformation
        ' Check the Error property before checking the Cancelled property:
        If e.Error IsNot Nothing Then
            Err_message(e.Error.Message)
        ElseIf e.Cancelled Then
            Err_message("Upload cancelled")
        End If

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.Close()
        End If

        Select Case CType(e.Result, Threads.MultiVersionThread.thread_result)
            Case Threads.MultiVersionThread.thread_result.rslt_allok_reset_required
                Err_message("Upload Complete")
                frmDisp = New frmInformation("ECU Reset", "Following the Uploading/Downloading for MAP Data to V1/V2 Bikirom Boards, an ECU reset maybe required", , MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_allok
                Err_message("Upload Complete")
            Case Threads.MultiVersionThread.thread_result.rslt_bikisoft_error
                frmDisp = New frmInformation("BikiSoft Error", "A Serious error was encountered that should have been handled internaly, " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_board_fault
                frmDisp = New frmInformation("BikiRom USB Board Error", "A Potential Board fault was detected, Or an extreme communication ropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_comms_error
                frmDisp = New frmInformation("BikiRom USB Communication Error", "A Communication dropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                frmDisp.ShowDialog()
        End Select

        thread_Remove(threadAction.TH_UPLOAD)
        thread_PendingDo()


        'MsgBox("Please reset ECU" & Chr(13) & "turn key off and on" & Chr(13) & "wait for all relays to turn off", MsgBoxStyle.Information, "Reset ECU")
    End Sub
    Private Sub bwUpload_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwUpload.DoWork
        Dim ul As TH_BikiRom_Up = CType(e.Argument, TH_BikiRom_Up)
        AddHandler ul.Progress, AddressOf EventBikiProgressUp
        AddHandler ul.Message, AddressOf EventBikiProgressUp

        ul.Execute(bwUpload, e)
    End Sub
    Private Sub bwUpload_CancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        If bwUpload.IsBusy Then
            bwUpload.CancelAsync()
        End If
    End Sub
    Private Sub bwUpload_RetryButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)

    End Sub

#End Region

#Region "-------------------------------- Thread -= Downloading"

    Private Sub bwDownload_Initialise(ByVal Action As BikiAction)
        ' create the progrss form
        Dim frm As New frmProgress("Download from Bikirom", New EventHandler(AddressOf bwDownload_CancelButton_Click))

        ' add item to queue
        m_cmdQueue.Enqueue(New Threads.QueueObj(bDownloadData(Action), threadAction.TH_DOWN, Action, frm))

        ' Nudge the queue
        thread_nudge()
    End Sub
    Private Function bDownloadData(ByVal Action As BikiAction) As TH_BikiRom_Down
        Dim bkDown As TH_BikiRom_Down = Nothing

        bkDown = New TH_BikiRom_Down(m_UsbCommHandler, m_newCar, Action)

        Return bkDown
    End Function
    Private Sub bDownAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mBSBdownload.Click
        bwDownload_Initialise(BikiAction.BK_EVERYTHING)
    End Sub
    Private Sub EventBikiProgress( _
       ByVal sender As Object, ByVal e As Threads.BikiThread_Args)

        ' A file was found. Report the progress, triggering the
        ' BackgroundWorker.ProgressChanged event:
        Dim intPercent As Integer = e.Progress
        If intPercent >= 100 Then
            intPercent = 100
        ElseIf intPercent < 0 Then
            intPercent = 0
        End If
        bwDownload.ReportProgress(intPercent, e)
    End Sub
    Private Sub bwDownload_ProgressChanges( _
        ByVal sender As Object, _
        ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwDownload.ProgressChanged
        Dim state As Threads.BikiThread_Args = CType(e.UserState, Threads.BikiThread_Args)

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.SetProgress(state.Progress)
            m_cmdCurrent.m_ProgressForm.AddMessage(state.Message)
        Else
            StatusPercent(state.Progress)
            Err_message(state.Message)
        End If

        If Not state.Object Is Nothing Then
            m_newCar = state.Object
            openInitialise()
            '    'm_newCar.getBikSettings.DownloadSettings()
            menu_Populate(m_newCar)
            m_currentFile = ""
            mFsaveAs.Enabled = True
        End If

    End Sub
    Private Sub bwDownload_RunWorkerCompleted( _
        ByVal sender As Object, _
        ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwDownload.RunWorkerCompleted
        Dim frmDisp As frmInformation

        ' Check the Error property before checking the Cancelled property:
        If e.Error IsNot Nothing Then
            Err_message(e.Error.Message)
        ElseIf e.Cancelled Then
            Err_message("Download cancelled")
        Else
            Try
                'If m_cmdCurrent.m_Action And BikiAction.BK_EVERYTHING Then
                '    m_currentFile = ""

                '    openInitialise()
                'End If
            Catch ex As Exception
                Err_message(Err.Description)
            End Try
        End If

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.Close()
        End If

        Select Case CType(e.Result, Threads.MultiVersionThread.thread_result)
            Case Threads.MultiVersionThread.thread_result.rslt_allok
                Err_message("Download Complete")
            Case Threads.MultiVersionThread.thread_result.rslt_allok_reset_required
                Err_message("Download Complete")
                frmDisp = New frmInformation("ECU Reset", "Following the Uploading/Downloading for MAP Data to V1/V2 Bikirom Boards, an ECU reset maybe required", , MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_bikisoft_error
                frmDisp = New frmInformation("BikiSoft Error", "A Serious error was encountered that should have been handled internaly, " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_board_fault
                frmDisp = New frmInformation("BikiRom USB Board Error", "A Potential Board fault was detected, Or an extreme communication ropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                If frmDisp.ShowDialog() = Windows.Forms.DialogResult.Retry Then

                End If
            Case Threads.MultiVersionThread.thread_result.rslt_comms_error
                frmDisp = New frmInformation("BikiRom USB Communication Error", "A Communication dropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                If frmDisp.ShowDialog() = Windows.Forms.DialogResult.Retry Then

                End If
        End Select

        Me.uiUpdate()

        thread_Remove(threadAction.TH_DOWN)
        thread_PendingDo()

    End Sub
    Private Sub bwDownload_DoWork(ByVal sender As System.Object, _
    ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwDownload.DoWork
        Dim bk As TH_BikiRom_Down = CType(e.Argument, TH_BikiRom_Down)
        AddHandler bk.Progress, AddressOf EventBikiProgress
        AddHandler bk.Message, AddressOf EventBikiProgress

        bk.Execute(bwDownload, e)
    End Sub
    Private Sub bwDownload_CancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        If bwDownload.IsBusy Then
            bwDownload.CancelAsync()
        End If
    End Sub

#End Region

#Region "-------------------------------- Thread -= Consult/Data Streams"
    Private Sub EventConsult(ByVal sender As Object, ByVal e As ConsultEventArgs)
        bwConsult.ReportProgress(0, e)
    End Sub

    Private Sub bwConsult_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwConsult.ProgressChanged
        Dim state As ConsultEventArgs = CType(e.UserState, ConsultEventArgs)
        If Not IsNothing(state) AndAlso Not IsNothing(Me.m_newCar) Then
            If state.Message <> "" Then
                Err_message(state.Message)
            End If
            If Not IsNothing(state.Stream) Then

                If Not IsNothing(m_EmulatorLog) Then
                    state.Stream.Add(New DataStream.StreamItem("EmulatorLast", DataStream.StreamItemType.Number, m_EmulatorLog.Last))
                    state.Stream.Add(New DataStream.StreamItem("EmulatorAddress", DataStream.StreamItemType.Number, m_EmulatorLog.Address))
                End If

                ' Add the caclculated data
                ConsultAddCalculatedData(state.Stream)

                ' Send stream item to be logged
                ConsultAddToStreamLog(state.Stream)

            End If
        End If
    End Sub
    Private Sub bwConsult_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwConsult.RunWorkerCompleted
        thread_Remove(threadAction.TH_CONSULT)
        Debug.Print("Consult Thread Finished")
        thread_PendingDo()
    End Sub
    Private Sub tmrConsult_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrConsult.Tick
        tmrConsult.Enabled = False
        If thread_CheckIfOK(threadAction.TH_CONSULT) And bConsult.Checked And m_cmdQueue.Count = 0 Then ' And rdConsultReplay.Checked = False Then
            If Not IsNothing(m_newCar) Then
                If thread_CheckIfOK(threadAction.TH_CONSULT) Then
                    thread_Add(threadAction.TH_CONSULT)
                    Dim ConsBw As New Consult(m_UsbCommHandler)

                    bwConsult.WorkerReportsProgress = True
                    bwConsult.WorkerSupportsCancellation = True

                    bwConsult.RunWorkerAsync(ConsBw)
                End If
                tmrConsult.Enabled = True
            Else
                tmrConsult.Enabled = True
                Return
            End If
        End If
        '' --------------------------------------------------- Start the consult thread if there is a connection and a -----------------------------------------------
        tmrConsult.Enabled = True
    End Sub
    Private Sub bwConsult_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwConsult.DoWork
        Dim bw As Consult = CType(e.Argument, Consult)
        AddHandler bw.Stream, AddressOf EventConsult
        bw.Execute(bwConsult, e)
    End Sub
    ''' <summary>
    ''' Calculates new values into the data stream. They can be used for many things..
    ''' </summary>
    ''' <param name="Stream"></param>
    ''' <remarks></remarks>
    Private Sub ConsultAddCalculatedData(ByRef Stream As DataStream.Stream)
        Dim tempValue As Double

        ' Move across Load into TP
        If Stream.contains("Load") Then
            Stream.Add(New DataStream.StreamItem("TP", DataStream.StreamItemType.Load, Stream("Load").Value))
        End If

        ' Check for the calculation of TP
        If Not Stream.contains("TP") And Stream.contains("RPM") And Stream.contains("AFM") Then
            Stream.Add(New DataStream.StreamItem("TP", DataStream.StreamItemType.Load, m_newCar.TP_calc(m_ptArray, Stream("RPM").Value, Stream("AFM").Value, 0)))
        End If

        ' Add ImperialTemp
        If Stream.contains("Temp") Then
            Stream.Add(New DataStream.StreamItem("Imp Temp", DataStream.StreamItemType.TEMP, (Stream("Temp").Value * (9 / 5) + 32) \ 1))
        End If

        ' Add ImperialSpeed
        If Stream.contains("Speed") Then
            Stream.Add(New DataStream.StreamItem("Imp Speed", DataStream.StreamItemType.Speed, Stream("Speed").Value / 1.609344))
        End If

        ' Add AFM %
        If Stream.contains("AFM") AndAlso Not IsNothing(m_newCar) Then
            Stream.Add(New DataStream.StreamItem("AFM%", DataStream.StreamItemType.Percent, (m_newCar.VQ_Value(m_ptArray, Stream("AFM").Value) / 65536.0!) * 100))
        End If

        ' Add Injector %
        If Stream.contains("RPM") AndAlso Stream.contains("Injector PW") Then
            If Stream("RPM").Value > 0 AndAlso Stream("Injector PW").Value > 0 Then
                tempValue = (Stream("Injector PW").Value / ((1 / (Stream("RPM").Value / 60)) * 2000)) * 100
            Else
                tempValue = 0
            End If
            Stream.Add(New DataStream.StreamItem("Injector PW%", DataStream.StreamItemType.Percent, tempValue))
        End If

        ' Perform user calculations
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamCalculator) Then
            m_newCar.StreamCalculator.RecieveStream(Stream)
        End If
        'Hook in stream calcualtor

        ' Temparary Code below
        ' Todo REMOVE THIS CODE FOOL!
        'If Stream.Contains("Aux2") AndAlso Stream.Contains("Aux1") Then
        '    Stream("Aux2").Value = (((Stream("Aux1").Value - uxLower.Value) / (uxUpper.Value - uxLower.Value)) * 90)
        'End If

    End Sub

    Private Sub ConsultAddToStreamLog(ByRef Stream As DataStream.Stream)
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(Me.m_newCar.StreamDB.CurrentStream) Then
            ' Add to log
            Dim timeDisplay As String = ""
            If (Stream.contains("RPM") AndAlso Stream("RPM").Value >= My.Settings.stream_trigger) _
            Or Not Stream.contains("RPM") Then
                Me.m_newCar.StreamDB.CurrentStream.Add(Stream)
                If Me.m_newCar.StreamDB.CurrentStream.Count = 1 Then
                    Me.RefreshValidStreamItems()
                End If
                If My.Settings.stream_current_auto_purge AndAlso Me.m_newCar.StreamDB.CurrentStream.StartTime > Now.AddHours(-8) _
                AndAlso Me.m_newCar.StreamDB.CurrentStream.Count > My.Settings.stream_current_auto_purge_time + 1 * 60 * 30 Then
                    Me.m_newCar.StreamDB.CurrentStream.Remove(0, Me.m_newCar.StreamDB.CurrentStream.Count - My.Settings.stream_current_auto_purge_time * 60 * 30)
                End If
                timeDisplay = "(Rec) "
            End If

            ' Update the timestamp display
            Dim time As TimeSpan = Stream.TimeStamp.Subtract(Me.m_newCar.StreamDB.CurrentStream.StartTime)
            timeDisplay &= String.Format("{0:00}:{1:00}:{2:00}.{3:000}", time.Hours, time.Minutes, time.Seconds, time.Milliseconds)
            uxDataLoggingTimeStamp.Text = timeDisplay

            ' Send to all controls if not recording
            If Me.m_newCar.StreamDB.CurrentStream.StreamPlaying Then
                RecieveStream(Stream)
            End If
        End If
    End Sub

    Private Sub rdFindNearest_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rdFindNearest.CheckedChanged

        If uxDockGrids.Count Then
            For i As Integer = uxDockGrids.Count To 1
                CType(uxDockGrids(i).Controls(0), Controls.DataGrid).FindNearest = rdFindNearest.Checked
            Next
        End If

    End Sub

    Private Sub bConsult_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bConsult.Click
        Try
            tmrConsult.Enabled = True
            Dim mnuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
            If mnuItem.Checked = True Then
                m_ConsultEnable = True
                SetRegistryKey("online", True)
            Else
                SetRegistryKey("online", False)
                m_ConsultEnable = False
                If thread_Check(threadAction.TH_CONSULT) Then bwConsult.CancelAsync()
            End If
        Catch
        End Try
    End Sub

    Private Sub consultClose()
        bwConsult.CancelAsync()
    End Sub
    Private Sub mDstream_Rename(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim menuItem As DataStreamLogToolStripMenuItem = CType(sender, DataStreamLogToolStripMenuItem)
        If Not IsNothing(m_newCar) _
        AndAlso Not IsNothing(m_newCar.StreamDB) _
        AndAlso m_newCar.StreamDB.Contains(menuItem.LogStartTime) Then
            Dim logDB As DataStream.StreamLogDB = m_newCar.StreamDB

            Dim name As String
            If menuItem.LogName <> "" Then
                name = String.Format("{0} {1} - {2}", menuItem.LogStartTime.ToShortDateString, menuItem.LogStartTime.ToShortTimeString, menuItem.LogName)
            Else
                name = String.Format("{0} {1}", menuItem.LogStartTime.ToShortDateString, menuItem.LogStartTime.ToShortTimeString)
            End If

            Dim frm As New frmBDialog("Enter a new name for '" & name & "''", "Rename Datalog", menuItem.LogName)

            If frm.ShowDialog = Windows.Forms.DialogResult.OK Then
                Dim log As DataStream.StreamLog = logDB(menuItem.LogStartTime)
                log.LogName = frm.Value
                logDB(menuItem.LogStartTime) = log
            End If
        End If
    End Sub
    Private Sub mDstream_Delete(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim menuItem As DataStreamLogToolStripMenuItem = CType(sender, DataStreamLogToolStripMenuItem)
        If Not IsNothing(m_newCar) _
        AndAlso Not IsNothing(m_newCar.StreamDB) _
        AndAlso m_newCar.StreamDB.Contains(menuItem.LogStartTime) Then
            Dim logDB As DataStream.StreamLogDB = m_newCar.StreamDB
            Dim name As String
            If menuItem.LogName <> "" Then
                name = String.Format("{0} {1} - {2}", menuItem.LogStartTime.ToShortDateString, menuItem.LogStartTime.ToShortTimeString, menuItem.LogName)
            Else
                name = String.Format("{0} {1}", menuItem.LogStartTime.ToShortDateString, menuItem.LogStartTime.ToShortTimeString)
            End If
            Dim frm As New BikiSoft.frmInformation("Delete Datalog", "Are you sure you want to delete this data log? Press Yes to delete this log", "Log name: '" & name & "''", MsgBoxStyle.YesNo Or MsgBoxStyle.Question)

            If frm.ShowDialog = Windows.Forms.DialogResult.Yes Then
                logDB.Remove(menuItem.LogStartTime)
            End If
        End If
    End Sub
    Private Sub mDstream_Open(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim menuItem As DataStreamLogToolStripMenuItem = CType(sender, DataStreamLogToolStripMenuItem)
        If Not IsNothing(m_newCar) _
        AndAlso Not IsNothing(m_newCar.StreamDB) _
        AndAlso m_newCar.StreamDB.Contains(menuItem.LogStartTime) Then
            Dim logDB As DataStream.StreamLogDB = m_newCar.StreamDB

            ' If Current Stream is not the one selected by menu
            If Not IsNothing(logDB.CurrentStream) AndAlso logDB.CurrentStream.StartTime <> menuItem.LogStartTime Then
                ' If this stream has already been saved check if it has changed since last being saved
                If logDB.Contains(logDB.CurrentStream.StartTime) Then
                    ' If the current stream isn't empty and it has changed from the one saved
                    If logDB.CurrentStream.Count > 0 _
                    AndAlso logDB.CurrentStream.Count <> logDB.DBEntries(logDB.CurrentStream.StartTime).Length Then

                        Select Case MsgBox("Current datalog has changed since last save, Save changes?", MsgBoxStyle.Question + MsgBoxStyle.YesNoCancel, "Save Datalog Changes?")
                            Case MsgBoxResult.Yes
                                ' Perform the saving of the current stream
                                logDB(logDB.CurrentStream.StartTime) = logDB.CurrentStream
                            Case MsgBoxResult.Cancel
                                Return
                        End Select

                    Else
                        ' Discard it, it hasn't changed or is empty.

                        Debug.Print("Empy selected")
                    End If
                ElseIf logDB.CurrentStream.Count > 0 Then
                    ' Assume the stream has never been saved before. Ask to save it
                    Select Case MsgBox("Current datalog has not been saved. Save Datalog?", MsgBoxStyle.Question + MsgBoxStyle.YesNoCancel, "Save New Datalog?")
                        Case MsgBoxResult.Yes
                            ' Perform the saving of the current stream
                            logDB.Add(logDB.CurrentStream)
                        Case MsgBoxResult.Cancel
                            Return
                    End Select

                End If
            Else
                Err_message("Datalog already opened")
            End If

            ' Set the current stream!
            m_newCar.StreamDB.SetCurrent(menuItem.LogStartTime)
            RefreshValidStreamItems()

            menu_DataLoggingPopulate()

            ' Seek to the begining. this should cause a complete re-draw!
            RaiseEvent Seek(Me, New DataStream.StreamSeekEventArgs(0))
        Else
            Err_message("Stream does not exist? Menu errors exist. BikiSoft fault, contact support@bikirom.com", message_type.MSG_Error)
        End If

    End Sub
    Private Sub mLoggingClearLogs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mLoggingClearLogs.Click
        If Not IsNothing(Me.m_newCar) AndAlso m_newCar.StreamDB.Count Then
            Dim frm As New BikiSoft.frmInformation("Delete Datalog(s)", "Are you sure you want to clear all data logs? Press Yes to clear all data logs", , MsgBoxStyle.YesNo Or MsgBoxStyle.Question)

            If frm.ShowDialog = Windows.Forms.DialogResult.Yes Then
                Me.m_newCar.StreamDB.Clear()
            End If
        End If
    End Sub
    Private Sub menu_DataLoggingPopulate()
        mVDStreams.DropDownItems.Clear()
        If Not IsNothing(m_newCar) AndAlso Not m_newCar.StreamDB Is Nothing Then
            Dim datalog As DataStream.StreamLogDB = m_newCar.StreamDB
            For Each item As DataStream.StreamLogDBItem In datalog
                Dim name As String
                If item.LogName <> "" Then
                    name = String.Format("{0} {1} - {2}", item.StartTime.ToShortDateString, item.StartTime.ToShortTimeString, item.LogName)
                Else
                    name = String.Format("{0} {1}", item.StartTime.ToShortDateString, item.StartTime.ToShortTimeString)
                End If

                Dim menuItem As New DataStreamLogToolStripMenuItem(name, AddressOf mDstream_Open, item)
                Dim menuOpen As New DataStreamLogToolStripMenuItem("Open", AddressOf mDstream_Open, item)
                Dim menuErase As New DataStreamLogToolStripMenuItem("Delete", AddressOf mDstream_Delete, item)
                Dim menuRename As New DataStreamLogToolStripMenuItem("Rename", AddressOf mDstream_Rename, item)
                menuItem.DropDownItems.Add(menuOpen)
                menuItem.DropDownItems.Add(menuRename)
                menuItem.DropDownItems.Add(menuErase)
                mVDStreams.DropDownItems.Add(menuItem)
            Next
        End If
    End Sub
    Private Sub uxDataLoggingSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxDataLoggingSave.Click
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then
            If m_newCar.StreamDB.Contains(m_newCar.StreamDB.CurrentStream.StartTime) Then
                Select Case MsgBox("Datalog already exists, Save changes?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Save Changes?")
                    Case MsgBoxResult.Cancel
                        Return
                    Case MsgBoxResult.Yes
                        ' Save the current datalog!
                        m_newCar.StreamDB(m_newCar.StreamDB.CurrentStream.StartTime) = m_newCar.StreamDB.CurrentStream
                        Me.m_saveRequired = True
                        Err_message("Datalog Saved")
                End Select
            Else
                ' Sabe the current datalog!
                Dim frm As New frmBDialog("Name for data log?", "Name Datalog", "")
                If frm.ShowDialog() = Windows.Forms.DialogResult.OK Then
                    m_newCar.StreamDB.CurrentStream.LogName = frm.Value
                End If

                m_newCar.StreamDB.Add(m_newCar.StreamDB.CurrentStream)
                Me.m_saveRequired = True
                menu_DataLoggingPopulate()
                Err_message("Datalog Added")
            End If
        End If
    End Sub
    Private Sub uxDataLoggingNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxDataLoggingNew.Click
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then
            Dim logDB As DataStream.StreamLogDB = m_newCar.StreamDB

            If logDB.CurrentStream.Count > 0 Then
                If logDB.Contains(logDB.CurrentStream.StartTime) Then

                    If logDB.CurrentStream.Count <> logDB.DBEntries(logDB.CurrentStream.StartTime).Length Then
                        ' Save current?
                        Select Case MsgBox("Discard current datalog changes?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Discard Changes?")
                            Case MsgBoxResult.Cancel
                                Return
                            Case MsgBoxResult.No
                                ' Save the current datalog!
                                logDB(logDB.CurrentStream.StartTime) = logDB.CurrentStream
                                Me.m_saveRequired = True
                        End Select

                    End If

                Else
                    ' Add New?
                    Select Case MsgBox("Current Datalog not saved, save before creating new?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Save Changes?")
                        Case MsgBoxResult.Yes
                            logDB.Add(logDB.CurrentStream)
                        Case MsgBoxResult.Cancel
                            Return
                    End Select

                End If
            End If

            ' Create a new stream
            menu_DataLoggingPopulate()
            logDB.CurrentStream = New DataStream.StreamLog
            RaiseEvent Seek(Me, New DataStream.StreamSeekEventArgs(0))
        End If
    End Sub
    Private Sub uxDataLoggingDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxDataLoggingDelete.Click
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then
            Dim logDB As DataStream.StreamLogDB = m_newCar.StreamDB

            If logDB.Contains(logDB.CurrentStream.StartTime) Then
                Select Case MsgBox("Are you sure?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Delete Datalog?")
                    Case MsgBoxResult.Yes
                        logDB.Remove(logDB.CurrentStream.StartTime)
                        Err_message("Datalog Deteted")
                    Case MsgBoxResult.Cancel, MsgBoxResult.No
                        Return
                End Select
                logDB.CurrentStream = New DataStream.StreamLog
            Else
                Select Case MsgBox("Clear current Datalog?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Delete Datalog?")
                    Case MsgBoxResult.Cancel, MsgBoxResult.No
                        Return
                    Case MsgBoxResult.Yes
                        Dim log As DataStream.StreamLog = logDB.CurrentStream
                        log.Clear()
                        logDB.CurrentStream = log
                End Select
            End If

            menu_DataLoggingPopulate()
            RaiseEvent Seek(Me, New DataStream.StreamSeekEventArgs(0))
        End If
    End Sub
    Private Sub uxDataLoggingPause_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxDataLoggingPause.Click
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(Me.m_newCar.StreamDB.CurrentStream) Then
            Me.m_newCar.StreamDB.CurrentStream.StreamPlaying = False
        End If
    End Sub
    Private Sub uxDataLoggingPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxDataLoggingPlay.Click
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(Me.m_newCar.StreamDB.CurrentStream) Then
            Me.m_newCar.StreamDB.CurrentStream.StreamPlaying = True
            Me.uxGraphOne.RefreshLog()
        End If
    End Sub
    ''' <summary>
    ''' Handles any current data logs changing
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub uxDataLogging_ChangedCurrent()

        Dim control As DataStream.IStreamHandle
        For Each obj As Object In m_StreamControls
            If Not obj.GetType.GetInterface("IStreamHandle", False) Is Nothing Then
                control = CType(obj, DataStream.IStreamHandle)
                control.RefreshLog()
            End If
        Next

        ' Assign the Valid Callback
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then
            m_newCar.StreamDB.CurrentStream.NewValidItemsCallback = AddressOf uxDataLogging_NewValidItems
            m_newCar.StreamDB.CurrentStream.StreamStateChangedCallback = AddressOf uxDataLogging_StreamStateChanged
        End If

    End Sub
    ''' <summary>
    ''' Handles new Valid Stream variables
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxDataLogging_NewValidItems(ByVal sender As Object, ByVal e As System.EventArgs)
        RefreshValidStreamItems()
    End Sub

    ''' <summary>
    ''' Handles the stream state changing (Restrict, Play/Pause)
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxDataLogging_StreamStateChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim stream As DataStream.StreamLog = CType(sender, DataStream.StreamLog)

        If stream.StreamPlaying Then
            dlogLabel.Text = "Recording"

            If uxDockGrids.Count Then
                For i As Integer = uxDockGrids.Count To 1
                    CType(uxDockGrids(i - 1).Controls(0), Controls.DataGrid).ClearStreamOverlay()
                Next
            End If
        Else
            dlogLabel.Text = "Paused"

            If Me.uxDataLoggingOverlay.Checked Then
                If uxDockGrids.Count Then
                    For i As Integer = uxDockGrids.Count To 1
                        CType(uxDockGrids(i - 1).Controls(0), Controls.DataGrid).GenerateStreamOverlay(stream)
                    Next
                End If
            Else
                If uxDockGrids.Count Then
                    For i As Integer = uxDockGrids.Count To 1
                        CType(uxDockGrids(i - 1).Controls(0), Controls.DataGrid).ClearStreamOverlay()
                    Next
                End If
            End If
        End If
    End Sub

#End Region

#Region "-------------------------------- Thread -= Emulator"

    'Private Sub EmulatorUploadTable()
    '    If m_live And Not IsNothing(m_newCar) And Not IsNothing(m_ptTable) Then
    '        Dim f_emuSetting As BVar = m_newCar.getConfig.getBikiVars.getByName("EMU")
    '        If Not IsNothing(f_emuSetting) And thread_CheckIfOK(threadAction.TH_EMUALTOR) And m_ptTable.EmulatorAble Then
    '            Dim f_emudata As Emulator
    '            thread_Add(threadAction.TH_EMUALTOR)
    '            If m_MapMirror = True And m_ptTable.Mirrorable And m_ptTable.Length > 0 Then
    '                Dim f_maps() As Table = m_newCar.getConfig.getTables.getTablesAsArray
    '                Dim f_targetArray(f_maps.Length - 1) As Integer
    '                Dim f_count As Int16
    '                For Each tab As Table In f_maps
    '                    If tab = m_ptTable And tab.Mirrorable Then
    '                        f_targetArray(f_count) = tab.Address
    '                        f_count += 1
    '                    End If
    '                Next
    '                ReDim Preserve f_targetArray(f_count - 1)
    '                f_emudata = New Emulator(m_ptArray, m_ptTable.Address, m_ptTable.Length, f_targetArray, f_emuSetting, 1, True)
    '            Else
    '                f_emudata = New Emulator(m_ptArray, m_ptTable.Address, m_ptTable.Length, m_ptTable.Address, f_emuSetting, 1, True)
    '            End If
    '            bwEmulator.WorkerReportsProgress = True
    '            bwEmulator.WorkerSupportsCancellation = True
    '            bwEmulator.RunWorkerAsync(f_emudata)
    '        End If
    '    End If
    'End Sub
    'Private Sub EventEmulator( _
    '    ByVal sender As Object, ByVal e As Emulator_Args)
    '    Dim intPercent As Integer = e.Progress
    '    bwEmulator.ReportProgress(intPercent, e)
    'End Sub
    'Private Sub bwEmulator_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwEmulator.ProgressChanged
    '    Dim state As Emulator_Args = CType(e.UserState, Emulator_Args)

    '    If state.Message <> "" Then
    '        Err_message(state.Message)
    '    End If
    '    StatusPercent(state.Progress)
    '    If state.Type <> "" Then
    '        stType.Text = state.Type
    '    End If
    'End Sub
    'Private Sub bwEmulator_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwEmulator.RunWorkerCompleted
    '    'Err_message("Emulator Upload complete")
    '    'Debug.Print("emualtor thread ended")
    '    thread_Remove(threadAction.TH_EMUALTOR)
    '    thread_PendingDo()
    '    If m_live Then
    '        ' stOnOff.Image = My.Resources.CHIP16
    '        tmrEmulator.Enabled = True
    '    Else
    '        Err_message("Emulator Not Initialised Or ERROR")
    '        '  stOnOff.Image = My.Resources.Status_Stop
    '    End If
    'End Sub
    'Private Sub bwEmulator_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwEmulator.DoWork
    '    Dim bw As Emulator = CType(e.Argument, Emulator)
    '    AddHandler bw.Type, AddressOf EventEmulator
    '    AddHandler bw.Message, AddressOf EventEmulator
    '    AddHandler bw.Progress, AddressOf EventEmulator

    '    bw.Execute(bwEmulator, e)
    'End Sub


    'Private Sub eUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles eUpload.Click
    '    If Not IsNothing(m_newCar) Then
    '        Dim f_emuSetting As BVar = m_newCar.getConfig.getBikiVars.getByName("EMU")
    '        If Not IsNothing(f_emuSetting) Then
    '            If thread_CheckIfOK(threadAction.TH_EMUALTOR) Then
    '                thread_Add(threadAction.TH_EMUALTOR)
    '                Dim f_emuData As New Emulator(m_ptArray, 0, 65536, 0, f_emuSetting, 1, False)
    '                bwEmulator.WorkerReportsProgress = True
    '                bwEmulator.WorkerSupportsCancellation = True

    '                bwEmulator.RunWorkerAsync(f_emuData)
    '                Debug.Print("Emuatlor INIT function started")
    '            Else
    '                MsgBox("BikiRom USB Busy, wait for Uploading/Download/Eraseing to finish and try again")
    '            End If
    '        End If
    '    End If
    'End Sub
    'Private Sub eStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles eStart.Click
    '    If MR_CheckIntrumentConnection = True Then
    '        m_EmulatorLog = New EmulatorLog(m_ptTable.Address, m_ptTable.Width, m_ptTable.Height, m_sixTeenBit)
    '        If m_sixTeenBit Then
    '            If MR_TraceSetRange(m_ptTable.Address \ 2, (m_ptTable.Address + m_ptTable.Length) \ 2) = False Then
    '                Err_message("Error setting Trace Range")
    '                Exit Sub
    '            End If
    '        Else
    '            If MR_TraceSetRange(m_ptTable.Address, (m_ptTable.Address + m_ptTable.Length)) = False Then
    '                Err_message("Error setting Trace Range")
    '                Exit Sub
    '            End If
    '        End If
    '        If MR_EmulationStart Then
    '            MR_LedSetMode(MR_LedModeT.MR_LED_BLINK_FAST)
    '        Else
    '            Err_message("Error starting emulation")
    '            Exit Sub
    '        End If
    '        MR_TraceStart()
    '        If Not IsNothing(m_ptTable) Then tmrEmulator.Enabled = True
    '        Err_message("Emulator Started")
    '        tmrEmulator.Enabled = True
    '        uxLinkStatus.Image = My.Resources.Status_Play
    '        m_emuStopStart = True
    '        gbEmulator.Visible = True
    '    End If
    'End Sub
    'Private Sub eStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles eStop.Click
    '    tmrEmulator.Enabled = False
    '    If MR_CheckIntrumentConnection = True Then
    '        MR_TraceStop()
    '        MR_EmulationStop()
    '        MR_LedSetMode(MR_LedModeT.MR_LED_BLINK_SLOW)
    '        Err_message("Emulator Stoped")
    '        uxLinkStatus.Image = My.Resources.Status_Stop
    '        m_emuStopStart = False
    '    End If
    'End Sub
    'Private Sub eClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles eClose.Click
    '    Emulator_Close()
    '    '  stOnOff.Image = My.Resources.Status_Stop
    '    uxLinkStatus.Image = My.Resources.Status_Stop
    'End Sub

    'Private Sub EmulatorTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrEmulator.Tick
    '    Dim m_emuBuffer(511) As Integer
    '    Dim m_emuBufferCount As Integer
    '    Try
    '        If Not thread_Check(threadAction.TH_EMUALTOR) And m_live And m_emuStopStart Then
    '            If MR_TraceReadData(m_emuBuffer(0), m_emuBufferCount) = False Then
    '                Err_message("EMU Trace ERR " & Str(MR_GetError))
    '            Else
    '                Try
    '                    Dim f_readBuff() As Integer = Nothing
    '                    If m_emuBufferCount >= 1 Then
    '                        ReDim f_readBuff(m_emuBufferCount - 1)
    '                        array_copy(m_emuBuffer, 0, f_readBuff, 0, m_emuBufferCount)
    '                        m_EmulatorLog.addRange(m_emuBuffer)
    '                        'dGrid.Invalidate()
    '                        'dGrid_Paint(dGrid, Nothing)
    '                        'Debug.Print(m_EmulatorLog.Grid.ToString)
    '                    End If
    '                Catch
    '                    Err_message("Error reporting Trace.. restart please")
    '                    'tmrEmulator.Enabled = False
    '                End Try
    '            End If
    '        End If
    '    Catch
    '    End Try
    'End Sub
    'Private Sub Emulator_TraceShow(ByRef EmuTraceLog As EmulatorLog)
    '    If Not IsNothing(m_ptTable) And Not IsNothing(m_EmulatorLog) Then
    '        If m_ptTable.Address = EmuTraceLog.Address Then
    '            Dim f_log(,) As Boolean = EmuTraceLog.Grid
    '            Dim tm_x, tm_y As Short
    '            For x As Int16 = 0 To f_log.GetUpperBound(0)
    '                For y As Int16 = 0 To f_log.GetUpperBound(1)
    '                    If f_log(x, y) Then
    '                        If m_ptTable.WidthInvert Then tm_x = (m_ptTable.Width - 1) - tm_x
    '                        If m_ptTable.HeightInvert Then tm_y = (m_ptTable.HeightInvert - 1) - tm_y
    '                        If m_ptTable.AxisSwap Then tm_x = y : tm_y = x Else tm_x = x : tm_y = y
    '                        dGrid.Item(x, y).Style.BackColor = Color.Cyan
    '                        dGrid.Item(x, y).Style.ForeColor = Color.Black
    '                    End If
    '                Next
    '            Next

    '        End If
    '    End If
    'End Sub
    'Private Sub Emulator_Close()
    '    Try
    '        MR_CloseCommunication()
    '        m_live = False
    '    Catch ex As Exception
    '    End Try
    'End Sub
    'Private Sub btnEmuShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEmuShow.Click
    '    tmrEmulator.Enabled = False
    '    Emulator_TraceShow(m_EmulatorLog)
    'End Sub
    'Private Sub btnEmuClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEmuClear.Click
    '    tmrEmulator.Enabled = True
    '    m_EmulatorLog.Clear()
    '    grid_Populate(dGrid)
    'End Sub
    Private Sub bMapMirror_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bMapMirror.Click
        Try
            Dim mnuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
            If mnuItem.Checked = True Then
                m_MapMirror = True
            Else
                m_MapMirror = False
            End If
        Catch
        End Try
    End Sub

#End Region

#Region "-------------------------------- Thread -= Firmware"
    Private Sub bwFirmware_Initialise()
        Dim f_FirmwareThread As New Threads.TH_firmware(Me.m_UsbHandler)

        Dim frm As New frmProgress("Updating BikiRom USB Firmware", New EventHandler(AddressOf bwFirmware_CancelButton_Click))

        m_cmdQueue.Enqueue(New Threads.QueueObj(f_FirmwareThread, threadAction.TH_FIRMWARE, Nothing, frm))

        thread_nudge()
    End Sub
    Private Sub bConfigFirmware_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bConfigFirmware.Click
        bwFirmware_Initialise()
    End Sub
    Private Sub bwFirmware_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwFirmware.ProgressChanged
        Dim state As Threads.BikiThread_Args = CType(e.UserState, Threads.BikiThread_Args)
        StatusPercent(state.Progress)
        Err_message(state.Message)

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.SetProgress(state.Progress)
            m_cmdCurrent.m_ProgressForm.AddMessage(state.Message)
        Else
            Err_message(state.Message)
            StatusPercent(state.Progress)
        End If

    End Sub
    Private Sub bwFirmware_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwFirmware.RunWorkerCompleted
        Dim frmDisp As frmInformation
        If e.Error IsNot Nothing Then
            Err_message(e.Error.Message)
        ElseIf e.Cancelled Then
            Err_message("Firmware Update Cancelled")
        End If

        If Not m_cmdCurrent.m_ProgressForm Is Nothing Then
            m_cmdCurrent.m_ProgressForm.Close()
        End If

        Select Case CType(e.Result, Threads.MultiVersionThread.thread_result)
            Case Threads.MultiVersionThread.thread_result.rslt_allok
                Err_message("Firmware Update Complete")
            Case Threads.MultiVersionThread.thread_result.rslt_bikisoft_error
                frmDisp = New frmInformation("BikiSoft Error", "A Serious error was encountered that should have been handled internaly, " & _
                "Update BikiSoft and Firmware to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.OkOnly)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_board_fault
                frmDisp = New frmInformation("BikiRom USB Error", "A Serious error was encountered when trying to update the Firmware, " & _
                                "Update BikiSoft to the latest version." & _
                                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.OkOnly)
                frmDisp.ShowDialog()
            Case Threads.MultiVersionThread.thread_result.rslt_comms_error
                frmDisp = New frmInformation("BikiRom USB Communication Error", "A Communication dropout/error was encourtered that could not automaticaly be resolved. Try resetting the BikiRom and try again. " & _
                "Update BikiSoft to the latest version." & _
                " and if the problem persists, contact BikiRom", , MsgBoxStyle.Information Or MsgBoxStyle.RetryCancel)
                frmDisp.ShowDialog()
        End Select

        thread_Remove(threadAction.TH_FIRMWARE)
        thread_PendingDo()
    End Sub
    Private Sub EventFirmware( _
       ByVal sender As Object, ByVal e As Threads.BikiThread_Args)

        ' A file was found. Report the progress, triggering the
        ' BackgroundWorker.ProgressChanged event:
        Dim intPercent As Integer = e.Progress
        If intPercent >= 100 Then
            intPercent = 100
        ElseIf intPercent < 0 Then
            intPercent = 0
        End If
        bwFirmware.ReportProgress(intPercent, e)
    End Sub
    Private Sub bwFirmware_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwFirmware.DoWork
        Dim fm As Threads.TH_firmware = CType(e.Argument, Threads.TH_firmware)
        AddHandler fm.Message, AddressOf EventFirmware
        AddHandler fm.Progress, AddressOf EventFirmware

        fm.Execute(bwFirmware, e)
    End Sub
    Private Sub bwFirmware_CancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        If bwFirmware.IsBusy Then
            bwFirmware.CancelAsync()
        End If
    End Sub
#End Region

#Region "-------------------------------- Thread -= BikiRom Commands"
    ''' <summary>
    ''' General Bikirom Command Thread ----------------------------------------------------------------------------------
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>These functions control the bikirom Command thread
    ''' Which do functions like upload to the eeprom space etc.
    ''' Commands that may take some time to process 
    ''' </remarks>
    Private Sub bwBikCmd_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwBikCmd.DoWork
        Dim bw As TH_Upload_EEPROM = CType(e.Argument, TH_Upload_EEPROM)
        AddHandler bw.Message, AddressOf bwBikCmd_EventHandler
        AddHandler bw.Progress, AddressOf bwBikCmd_EventHandler

        bw.Execute(bwBikCmd, e)
    End Sub
    Private Sub bwBikCmd_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwBikCmd.ProgressChanged
        Dim state As Threads.BikiThread_Args = CType(e.UserState, Threads.BikiThread_Args)
        StatusPercent(state.Progress)
        Err_message(state.Message)
    End Sub
    Private Sub bwBikCmd_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwBikCmd.RunWorkerCompleted
        On Error Resume Next
        If e.Error IsNot Nothing Then
            Err_message(e.Error.Message)
        ElseIf e.Cancelled Then
            Err_message("BikiRom Command Cancelled")
        Else
            ''------------ SUCCESS!!!! Update the usb biki crc
            '- This code is now done inside the eprom upload thread so it knows if it did it properly or not
            ' If m_cmdCurrent.m_Process = threadAction.TH_BIK_UPLOAD Then
            'Dim f_crc As New CRC32
            'If BikiRom_connect() = BK_return.BK_OK Then SetUsbVariable(Biki_USBvars.UV_BikEEPROM_CRC, f_crc.GetByteArrayCrc32(m_newCar.getBikSettings.getData))
            'End If
        End If
        thread_Remove(threadAction.TH_BIK_UPLOAD)
        thread_PendingDo()
    End Sub
    Private Sub bwBikCmd_EventHandler(ByVal sender As System.Object, ByVal e As Threads.BikiThread_Args)
        Dim intPercent As Integer = e.Progress
        If intPercent >= 100 Then
            intPercent = 100
        ElseIf intPercent < 0 Then
            intPercent = 0
        End If
        bwBikCmd.ReportProgress(intPercent, e)
    End Sub
#End Region

#Region "-------------------------------- Thread -= Master Control Functions and Subs"
    ''' <summary>
    ''' Thread Handling Functions
    ''' </summary>
    Friend Sub thread_Close(ByVal TH As threadAction)
        Select Case TH
            Case threadAction.TH_CMD
                If bwBikCmd.IsBusy Then Me.bwBikCmd.CancelAsync()
            Case threadAction.TH_EMUALTOR
                If bwEmulator.IsBusy Then Me.bwEmulator.CancelAsync()
            Case threadAction.TH_DOWN
                If bwDownload.IsBusy Then bwDownload.CancelAsync()
            Case threadAction.TH_UPLOAD
                If bwUpload.IsBusy Then bwUpload.CancelAsync()
            Case threadAction.TH_CONSULT
                If bwConsult.IsBusy Then bwConsult.CancelAsync()
            Case threadAction.TH_FIRMWARE
                If bwFirmware.IsBusy Then bwFirmware.CancelAsync()
        End Select
    End Sub
    Friend Shared Function thread_Pending() As Boolean
        If m_cmdQueue.Count <> 0 Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Nudges the thread queue
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Function thread_nudge() As Boolean
        If thread_Pending() And thread_Check(threadAction.TH_CONSULT) Then
            consultClose()
        ElseIf thread_CheckIfOK(threadAction.TH_CMD) Then
            thread_PendingDo()
        End If
    End Function

    ''' <summary>
    ''' Call this sub routine ONLY at the end of another thread, or is NO other threads are currently active
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub thread_PendingDo()
        m_cmdCurrent = Nothing
        If m_cmdQueue.Count >= 1 Then
            Err_message("Executing command in Queue, Ctl+Break to stop")
            m_cmdCurrent = CType(m_cmdQueue.Dequeue, Threads.QueueObj)
            If thread_CheckIfOK(m_cmdCurrent.m_Process) Then
                Select Case m_cmdCurrent.m_Process
                    Case threadAction.TH_ERASEDATALOGS
                        mVDEraseDatalogs.PerformClick()
                    Case threadAction.TH_BIKSEC
                        bConfigSecurity.PerformClick()
                    Case threadAction.TH_BIKPASS
                        bConfigPassword.PerformClick()
                    Case threadAction.TH_DOWN
                        Debug.Print("Downloading after a consult thread ended...")

                        If Not IsNothing(m_cmdCurrent.m_Object) Then

                            thread_Add(threadAction.TH_DOWN)
                            bwDownload.RunWorkerAsync(m_cmdCurrent.m_Object)

                            m_cmdCurrent.m_ProgressForm.ShowDialog()
                        End If
                    Case threadAction.TH_UPLOAD
                        '------------------------------------------------------------------------------------------
                        ' Performs an upload to the Board. Hooks in new status forms and all
                        '
                        'Debug.Print("Uploading after a consult thread ended...")

                        If Not IsNothing(m_cmdCurrent.m_Object) Then
                            thread_Add(threadAction.TH_UPLOAD)
                            bwUpload.RunWorkerAsync(m_cmdCurrent.m_Object)

                            m_cmdCurrent.m_ProgressForm.ShowDialog()
                        End If
                    Case threadAction.TH_DATALOG
                        If Not IsNothing(m_cmdCurrent.m_Object) Then
                            thread_Add(threadAction.TH_DATALOG)
                            bwDatalog.RunWorkerAsync(m_cmdCurrent.m_Object)

                            m_cmdCurrent.m_ProgressForm.ShowDialog()
                        End If
                    Case threadAction.TH_ERASE
                        Call bConfigErase.PerformClick()
                    Case threadAction.TH_FIRMWARE
                        ' Update Firmware

                        If BikiRom_connect() = BK_return.BK_OK Then
                            If BikiRom_Init() = BK_return.BK_OK AndAlso _
                                   ((m_UsbCommHandler.UsbInformation.OsVersion > My.Settings.Firmware_Version AndAlso _
                                   m_UsbCommHandler.UsbInformation.BoardVersion = Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV2 AndAlso _
                                   m_UsbCommHandler.UsbInformation.BoardVersion = Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV1) Or _
                                   (m_UsbCommHandler.UsbInformation.OsVersion > My.Settings.Firmware_Version_33 AndAlso _
                                   m_UsbCommHandler.UsbInformation.BoardVersion = Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV3)) _
                            Then
                                Err_message("Firmware Already Updated. No action required")
                                Exit Sub
                            End If

                            thread_Add(threadAction.TH_FIRMWARE)
                            bwFirmware.WorkerReportsProgress = True
                            bwFirmware.WorkerSupportsCancellation = True
                            bwFirmware.RunWorkerAsync(m_cmdCurrent.m_Object)

                            m_cmdCurrent.m_ProgressForm.ShowDialog()
                        End If

                    Case threadAction.TH_BIKCODE
                        bConfigUpgrade.PerformClick()
                    Case threadAction.TH_EMUALTOR
                        If Not IsNothing(m_cmdCurrent.m_Object) Then
                            thread_Add(m_cmdCurrent.m_Process)
                            bwEmulator.RunWorkerAsync(m_cmdCurrent.m_Object)
                        End If
                    Case threadAction.TH_BIK_UPLOAD
                        If Not IsNothing(m_cmdCurrent.m_Object) Then
                            thread_Add(threadAction.TH_BIK_UPLOAD)
                            bwBikCmd.RunWorkerAsync(m_cmdCurrent.m_Object)
                        End If
                        'mBSBupload.PerformClick()
                    Case threadAction.TH_BIK_DOWNLOAD
                        mBSEdownload.PerformClick()
                    Case threadAction.TH_SYNC_UPLOAD
                        Me.mBSyncUpload.PerformClick()
                    Case threadAction.TH_SYNC_DOWNLOAD
                        Me.mBSyncDown.PerformClick()
                    Case Else
                        m_cmdCurrent = Nothing
                End Select
            End If
        End If
    End Sub
#End Region

#Region "-------------------------------- Form Events"
    ''' <summary>
    ''' Passes up any exceptions that have gone unhandled or explicitle called from
    ''' the communications threads
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Communication_ExceptionHandler(ByVal sender As Object, ByVal e As Comm.UsbCommunicationStatusEventArgs) Handles m_UsbHandler.CommunicationExceptionEventHandler
        If Me.InvokeRequired Then
            Me.Invoke(New Communication_ExceptionHandlerDelegate(AddressOf Communication_ExceptionHandler), (New Object() {sender, e}))
        Else

            Dim form As New frmInformation("USB Communication Problem", _
                           e.Message, , _
                           MsgBoxStyle.Information Or MsgBoxStyle.OkCancel)

            form.ShowDialog()

            ' Err_message(e.Description, message_type.MSG_Error)
        End If
    End Sub
    Private Delegate Sub Communication_ExceptionHandlerDelegate(ByVal sender As Object, ByVal e As Comm.UsbCommunicationStatusEventArgs)

    ''' <summary>
    ''' This function happens whenever the communications status change from connected to disconnect
    ''' etc etc
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Communication_StatusEvent(ByVal sender As Object, ByVal e As Comm.UsbCommunicationStatusEventArgs) Handles m_UsbHandler.CommunicationStatusEventHandler
        If Me.InvokeRequired Then
            Me.Invoke(New Communication_StatusEventDelegate(AddressOf Communication_StatusEvent), (New Object() {sender, e}))
        Else
            Dim Handler As Comm.UsbCommunicationHandle = CType(sender, Comm.UsbCommunicationHandle)

            If e.IsConnected And e.IsInitialised Then

                uxLinkStatus.Image = Me.uxImgList.Images(0)

                Err_message(e.Message, message_type.MSG_Infomation)
            Else
                uxLinkStatus.Image = Me.uxImgList.Images(1)

                Err_message(e.Message, message_type.MSG_Error)
            End If
        End If

    End Sub
    Private Delegate Sub Communication_StatusEventDelegate(ByVal sender As Object, ByVal e As Comm.UsbCommunicationStatusEventArgs)

    ''' <summary>
    ''' Event specifies that communication has been established with an initialisation
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Communication_Established(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_UsbHandler.CommunicationEstablished

        tmrConsult.Enabled = True
        tmrConsult.Start()
        ' Load a file if one not already loaded!

        ' Enable timer to open file and what not
    End Sub

    Private Sub frmBikiMain_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effect = DragDropEffects.Copy
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub
    Private Sub frmBikiMain_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
        Try
            Dim a As Array = e.Data.GetData(DataFormats.FileDrop)
            If Not IsNothing(a) Then
                Dim s As String = a.GetValue(0).ToString
                ' Do if file is already open, IMPORT!
                If Not IsNothing(m_newCar) Then
                    If GetExtension(s) = "bbd" Then
                        iBase.Tag = s
                        iBase.PerformClick()
                    ElseIf GetExtension(s) = "bin" Or GetExtension(s) = "bik" Or GetExtension(s) = "bik2" Then
                        iMap.Tag = s
                        iMap.PerformClick()
                    End If
                Else ' Do if file not open, Open!
                    If GetExtension(s) = "bin" Or GetExtension(s) = "bik" Or GetExtension(s) = "bik2" Then
                        mFopen.Tag = s
                        mFopen.PerformClick()
                    End If
                End If
            End If
        Catch ex As Exception
            Err_message("Invalid file format, Drag Drop failed")
        End Try
    End Sub

    ''' <summary>
    ''' This function will display the currently linked Grid in the 3d graph 
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub tmrGraph_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGraph.Tick
        If Not IsNothing(m_newCar) And Not IsNothing(m_ptArray) Then

            Try
                If Not IsNothing(Graph3D1.Dx) AndAlso Not IsNothing(uxDockGridFocus) AndAlso Not uxDockGridFocus.IsDisposed Then
                    m_ptTable.getTable(uxDockGridFocus.Data, uxDockGridFocus, Graph3D1)
                    Graph3D1.ReGenerate()
                End If
            Catch ex As Exception
                Err_message("Unable to draw 3d graph, directX issue", message_type.MSG_Infomation)
                tmrGraph.Enabled = False
            End Try
            
        End If

        tmrGraph.Enabled = False
    End Sub

    ''' <summary>
    ''' Auto Speed Scaling Timer. Put all speed scaling calculations in this function
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub tmrIdle_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrIdle.Tick
        ' Console.WriteLine(pcIdle.NextValue())

        'If My.Settings.stream_auto Then
        '    Dim fProcs As Integer = Environment.ProcessorCount - 1
        '    Dim dblIdle As Double = (pcIdle.NextValue) - (fProcs * 100)
        '    Dim dblAvg As Double = (dblIdle + CDbl(sender.tag)) / 2
        '    If dblAvg < 40 Then
        '        If My.Settings.stream_delay < 20 Then

        '            sender.tag = 50
        '            My.Settings.stream_delay += 1
        '            'Console.WriteLine("Speed Steping down")
        '        End If
        '    ElseIf dblAvg > 60 Then
        '        If My.Settings.stream_delay > 1 Then

        '            sender.tag = 50
        '            My.Settings.stream_delay -= 1
        '            'Console.WriteLine("Speed Steping up")
        '        End If
        '    Else
        '        sender.tag = dblAvg
        '    End If
        'End If
    End Sub

#End Region

#Region "-------------------------------- Form Button Click Events"
    Private Sub VersionItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mHVersion.Click
        MsgBox("Version " & Application.ProductVersion, MsgBoxStyle.Information, "Version")
    End Sub
    Private Sub bConfigSecurity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bConfigSecurity.Click
        Dim f_ret As BK_return
        Dim f_frame As Comm.Comm_Frame

        If thread_CheckIfOK(threadAction.TH_CMD) Then
            thread_Add(threadAction.TH_CMD)
            Dim f_return(6) As Byte
            f_ret = BikiRom_Init()
            If f_ret = BK_return.BK_OK Then
                m_UsbCommHandler.Timeout = 12000
                Dim dialog As New frmSecuritySet
                If dialog.ShowDialog = Windows.Forms.DialogResult.OK Then
                    Err_message("Attempting to set new Security Level")
                    Dim f_packet(16) As Byte
                    Array.Copy(dialog.SecurityCode, 0, f_packet, 0, 16)
                    f_packet(16) = dialog.SecuityMode

                    Try
                        f_frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , Comm.Comm_Frame.BikiFrameAction.RUN_SEC_SETSECLEVEL, f_packet, Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                        m_UsbCommHandler.SendFrame(f_frame, , True)
                        Err_message(dialog.SecurityModeDesc & " Set OK!")
                    Catch exComm As Comm_Exceptions
                        Err_message(exComm.Description)
                    Catch exUsb As USB_exceptions
                        Err_message(exUsb.Description)
                    End Try
                End If
            Else
                errDisplay(f_ret)
            End If
            thread_Remove(threadAction.TH_CMD)
        Else
            If thread_Check(threadAction.TH_CONSULT) Then
                m_cmdQueue.Enqueue(New Threads.QueueObj(Nothing, threadAction.TH_BIKSEC, Nothing))
                bwConsult.CancelAsync()
            Else
                MsgBox("Communications In Use, Wait for other actions to finish and try again")
            End If
        End If
    End Sub
    Private Sub bConfigPassword_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bConfigPassword.Click
        Dim f_ret As BK_return
        Dim f_frame As Comm.Comm_Frame

        If thread_CheckIfOK(threadAction.TH_CMD) Then
            thread_Add(threadAction.TH_CMD)
            Dim f_return(6) As Byte
            f_ret = BikiRom_Init()
            If f_ret = BK_return.BK_OK Then
                m_UsbCommHandler.Timeout = 12000
                Dim str As String = ""

                str = InputBox("Enter Passphase", "Security Password", "")

                If str.Length > 0 Then
                    Dim salt As Byte() = {23, 45, 67, 89}
                    Dim password As New PasswordDeriveBytes(str, salt, "SHA384", 1000)

                    Err_message("Trying to set new Password")
                    Try
                        f_frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , Comm.Comm_Frame.BikiFrameAction.RUN_SEC_SETPASSWORD, password.GetBytes(16), Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                        m_UsbCommHandler.SendFrame(f_frame, , True)
                        Err_message("New password OK!")
                    Catch exComm As Comm_Exceptions
                        Err_message("You must be in Security Level 1 to set new password")
                    Catch exUsb As USB_exceptions
                        Err_message(exUsb.Description)
                    End Try
                End If
            Else
                errDisplay(f_ret)
            End If
            thread_Remove(threadAction.TH_CMD)
        Else
            If thread_Check(threadAction.TH_CONSULT) Then
                m_cmdQueue.Enqueue(New Threads.QueueObj(Nothing, threadAction.TH_BIKPASS, Nothing))
                bwConsult.CancelAsync()
            Else
                MsgBox("Communications In Use, Wait for other actions to finish and try again")
            End If
        End If
    End Sub
    Private Sub bConfigUpgrade_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bConfigUpgrade.Click
        Dim f_ret As BK_return
        Dim f_frame As Comm.Comm_Frame

        If thread_CheckIfOK(threadAction.TH_CMD) Then
            thread_Add(threadAction.TH_CMD)
            Dim f_return(6) As Byte
            f_ret = BikiRom_Init()
            If f_ret = BK_return.BK_OK Then
                m_UsbCommHandler.Timeout = 12000
                Dim str As String = ""
                While str.Length <> 32
                    str = InputBox("Enter 32 Character Upgrade Code", "Upgrade Code", "")
                    If str.Length = 0 Then Exit While
                End While
                If str.Length = 32 Then
                    Err_message("Trying entered unlock Code")
                    Try
                        f_frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , Comm.Comm_Frame.BikiFrameAction.RUN_SEC_UNLOCKCODE, cv_BytesFromHex(str), Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                        m_UsbCommHandler.SendFrame(f_frame, , True)
                        Err_message("Unlock Code OK!")
                    Catch exComm As Comm_Exceptions
                        Err_message(exComm.Description)
                    Catch exUsb As USB_exceptions
                        Err_message(exUsb.Description)
                    End Try
                End If
            Else
                errDisplay(f_ret)
            End If
            thread_Remove(threadAction.TH_CMD)
        Else
            If thread_Check(threadAction.TH_CONSULT) Then
                m_cmdQueue.Enqueue(New Threads.QueueObj(Nothing, threadAction.TH_BIKCODE, Nothing))
                bwConsult.CancelAsync()
            Else
                MsgBox("Communications In Use, Wait for other actions to finish and try again")
            End If
        End If
    End Sub
    Private Sub mVOptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVOptions.Click
        Dim Options As New frmOptionsDialog()
        Options.Show()
    End Sub
    Private Sub mBSBupload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mBSEuploadAll.Click
        bwUpload_InitialiseUpload(BikiAction.BK_EEPROM)
    End Sub
    Private Sub mBSBdownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mBSEdownload.Click
        bwDownload_Initialise(BikiAction.BK_EEPROM)
    End Sub
    Private Sub cnGraphAFM_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGraphTPTrace.DoubleClick, cnGraphTps.DoubleClick, cnGraphTemp.DoubleClick, cnGraphSpeed.DoubleClick, cnGraphRPM.DoubleClick, cnGraphO2.DoubleClick, cnGraphInj.DoubleClick, cnGraphIgn.DoubleClick, cnGraphAFM.DoubleClick
        Dim f_sender As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        For Each opt As ToolStripMenuItem In f_sender.Owner.Items
            If opt.CheckState = CheckState.Indeterminate Then opt.CheckState = CheckState.Checked
        Next
        f_sender.CheckState = CheckState.Indeterminate
    End Sub

    ''' <summary>
    ''' This subroutine Syncronises the currently openen and editing file to the Bikirom, updates all nessesary changes if something has changed
    ''' </summary>
    ''' <param name="sender">.tag = "upload" or "download"</param>
    ''' <param name="e"></param>
    ''' <remarks>Main Sync Routine</remarks>
    Private Sub Syncronise_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mBSyncUpload.Click, mBSyncDown.Click, SaveToUSBToolStripMenuItem.Click, OpenUSBToolStripMenuItem.Click, mBSyncEcuOnly.Click
        Dim f_menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)

        If Not IsNothing(m_newCar) Then

            If m_currentFile <> "" And m_UsbCommHandler.UsbInformation.SerialNo <> "" Then SetRegistryKey(m_UsbCommHandler.UsbInformation.SerialNo, m_currentFile, "AutoLoad")

            Select Case CType(f_menuItem.Tag, String)
                Case "ecuonly"
                    bwUpload_InitialiseUpload(BikiAction.BK_MAPS)
                Case "upload"
                    bwUpload_InitialiseUpload(BikiAction.BK_MAPS Or BikiAction.BK_EEPROM)
                Case "download"
                    bwDownload_Initialise(BikiAction.BK_MAPS Or BikiAction.BK_EEPROM)
                Case "save"
                    bwUpload_InitialiseUpload(BikiAction.BK_EVERYTHING)
                Case "open"
                    bwDownload_Initialise(BikiAction.BK_EVERYTHING)
                Case Else
                    Throw New ArgumentException("Invalid Arguments setup for BikiRom Control, Error in compilation")
            End Select

        Else
            If CType(f_menuItem.Tag, String) = "open" Then
                bwDownload_Initialise(BikiAction.BK_EVERYTHING)
            End If
        End If
    End Sub
    Private Sub HelpToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mHHelp.Click
        DisplayHelp()
    End Sub

    Private Sub mVDiagnostics_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVDiagnostics.Click
        If IsNothing(m_Diagnostics) Then
            m_Diagnostics = New frmDiagnostics(m_newCar, m_UsbCommHandler)
        ElseIf m_Diagnostics.IsDisposed Then
            m_Diagnostics = New frmDiagnostics(m_newCar, m_UsbCommHandler)
        End If

        If Not m_Diagnostics.Visible Then
            InitialiseStreamControl(m_Diagnostics)
            m_Diagnostics.Show()
        End If

    End Sub
    Private Sub bErase_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bConfigErase.Click
        If thread_CheckIfOK(threadAction.TH_ERASE) Then
            Dim iQuestion As Integer = MsgBox("Are you sure you want to erase all data from your BikiRom?", MsgBoxStyle.OkCancel, "Erase BikiRom?")
            If iQuestion = vbOK Then
                If BikiRom_Init() = BK_return.BK_OK Then
                    Err_message("Erasing............")
                    If BikiRom_EraseSector(BikiAction.BK_ALL) = BK_return.BK_OK Then
                        m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_BikEEPROM_CRC, 0)
                        m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC, 0)
                        m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_2, 0)
                        m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, 0)
                        Err_message("BikiR0M Erased!")
                    Else
                        Err_message("Error: Erase Failed")
                    End If
                Else
                    Err_message("Error: Erase Failed")
                End If
            End If
        Else
            If thread_Check(threadAction.TH_CONSULT) Then consultClose()
            m_cmdQueue.Enqueue(New Threads.QueueObj(Nothing, threadAction.TH_ERASE, BikiAction.BK_ALL))
        End If
    End Sub
    Private Sub mECancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mECancel.Click
        Err_message("Canceling Active Jobs")
        m_cmdQueue = New Threads.Queue
        bwConsult.CancelAsync()
        bwDownload.CancelAsync()
        bwUpload.CancelAsync()
        bwEmulator.CancelAsync()
        bwBikCmd.CancelAsync()
        m_UsbCommHandler.Close()
    End Sub
    Friend Sub DisplayHelp()
        ' The file to display is chosen by the value of the topic
        ' parameter.
        Windows.Forms.Help.ShowHelp(Me, Application.StartupPath & "\BikiSoft.chm", HelpNavigator.TableOfContents)

    End Sub
    Private Sub mHEShowAUlogic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mHEShowAUlogic.Click
        Dim frmTest As New frmAUNodeTest(Me.m_newCar)
        frmTest.Show()
    End Sub
#End Region

#Region "-------------------------------- 3D Graphing Events"
    Private Sub btnDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDown.Click
        Graph3D1.LookUpDown += 3
    End Sub
    Private Sub btnUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUp.Click
        Graph3D1.LookUpDown -= 3
    End Sub
    Private Sub btnLeft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLeft.Click
        Graph3D1.LookLeftRight += 5
    End Sub
    Private Sub btnRight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRight.Click
        Graph3D1.LookLeftRight -= 5
    End Sub
#End Region

    Private Sub tmrClrMessage_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrClrMessage.Tick
        If stMsg.Text = sender.tag Then
            stMsg.Text = ""
        End If
        tmrClrMessage.Enabled = False
    End Sub
    Private Sub errDisplay(ByVal errCode As BK_return)
        If errCode <> BK_return.BK_OK Then
            Err_message(Err_Decode(errCode))
        End If
    End Sub

#Region "--------------------------------  New Stream control/recieve/display events"

#End Region

#Region "-------------------------------- View Desktop Settings menu Events/Menu Generator etc"

    ''' <summary>
    ''' Saves the current desktop setting to whatever "current" is
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxViewDesktopSettingsSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxViewDesktopSettingsSave.Click
        DesktopSettingSave(Me.m_UserDesktopSettings.CurrentDesktop)
    End Sub

    ''' <summary>
    ''' Specifies a new desktop setting to be saved, retrieve name from user
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxViewDesktopSettingsSaveAs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxViewDesktopSettingsSaveAs.Click
        ' Create the new settings
        Dim settingsName As String = ""
        Dim settings As UI.UserDesktopSettings = Nothing
ask:    settingsName = InputBox("Enter a name for your desktop setting", "Save Desktop Layout", "")

        If settingsName <> "" Then
            ' Create or get if over-writing
            If Me.m_UserDesktopSettings.Contains(settingsName) Then
                Select Case MsgBox("Layout name already exists, Yes to overwrite or No to enter new name?", MsgBoxStyle.YesNoCancel, "Name already exists")
                    Case MsgBoxResult.Yes
                        settings = Me.m_UserDesktopSettings(settingsName)
                    Case MsgBoxResult.No
                        GoTo ask
                    Case MsgBoxResult.Cancel
                        Return
                End Select
            Else
                settings = New UI.UserDesktopSettings(settingsName)
                Me.m_UserDesktopSettings.Add(settings)
            End If

            ' Do the actual saving now
            DesktopSettingSave(settings)

            ' Set it as the current
            Me.m_UserDesktopSettings.CurrentDesktop = settings

            ' Re-generate the menu's now
            DesktopSettingsGenerateMenuItems(Me.uxViewDesktopSettings)

        End If
    End Sub

    ''' <summary>
    ''' Specifies a desktop setting to delete
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxViewDesktopSettingsDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxViewDesktopSettingsDelete.Click
        Me.m_UserDesktopSettings.DeleteCurrentDesktop()

        ' Re-generate the menu's now
        DesktopSettingsGenerateMenuItems(Me.uxViewDesktopSettings)
    End Sub

    ''' <summary>
    ''' Performs a re-configure to occur
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxViewDesktopSettingsItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim menuItem As uxViewDesktopSettingsMenuItem = CType(sender, uxViewDesktopSettingsMenuItem)
        If Not menuItem.DesktopSettings Is Nothing Then
            Me.m_UserDesktopSettings.CurrentDesktop = menuItem.DesktopSettings
            DesktopSettingApply(m_UserDesktopSettings.CurrentDesktop)
        End If
    End Sub

    ''' <summary>
    ''' Applies a given desktop setting to the current application
    ''' </summary>
    ''' <param name="Settings"></param>
    ''' <remarks></remarks>
    Private Sub DesktopSettingApply(ByVal Settings As UI.UserDesktopSettings)
        Dim control As DataStream.IStreamConfig
        For Each setting As UI.UserStreamControlSettings In Settings.StreamControlSettings
            'If m_StreamControls.Contains(setting.Name) Then
            '    Dim obj As Object = m_StreamControls(setting.Name)
            '    If Not obj.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing Then
            '        control = CType(obj, DataStream.IStreamConfig)
            '        setting.ApplySettings(control)
            '    End If
            'End If
            For Each obj As Object In m_StreamControls
                If Not obj.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing Then
                    control = CType(obj, DataStream.IStreamConfig)
                    ' Match the setting to the control
                    If control.Name = setting.Name Then
                        ' Apply the settings to the control
                        setting.ApplySettings(control)
                        Exit For
                    End If
                End If
            Next
        Next

        Me.mV2Dtrace.Checked = Settings.Graph2DVisible
        Me.mV3d.Checked = Settings.Graph3DVisible
        If Not IsNothing(uxDockGridFocus) AndAlso Not uxDockGridFocus.IsDisposed Then
            Me.rdFindNearest.Checked = uxDockGridFocus.FindNearest
        End If
    End Sub

    ''' <summary>
    ''' Saves to the passed settings from the current form
    ''' </summary>
    ''' <param name="Settings"></param>
    ''' <remarks></remarks>
    Private Sub DesktopSettingSave(ByVal Settings As UI.UserDesktopSettings)
        'Dim Settings As UI.UserDesktopSettings = Me.m_UserDesktopSettings.CurrentDesktop
        Dim Setting As UI.UserStreamControlSettings = Nothing

        Dim control As DataStream.IStreamConfig
        For Each obj As Object In m_StreamControls
            If Not obj.GetType.GetInterface(GetType(DataStream.IStreamConfig).FullName, True) Is Nothing Then
                control = CType(obj, DataStream.IStreamConfig)
                If Settings.StreamControlSettings.Contains(control.Name) Then
                    ' Save to current
                    Setting = Settings.StreamControlSettings(control.Name)
                Else
                    ' Create new
                    Setting = New UI.UserStreamControlSettings(control.Name)
                    Settings.StreamControlSettings.Add(Setting)
                End If
                ' Save the actual setting
                Setting.SaveSetting(control)
            End If
        Next

        Settings.Graph2DVisible = Me.mV2Dtrace.Checked
        Settings.Graph3DVisible = Me.mV3d.Checked
    End Sub

    ''' <summary>
    ''' This function will generate all the relevent menu items for the user
    ''' desktop settings class, also note it will clear out any pre-existing ones
    ''' </summary>
    ''' <param name="Menu"></param>
    ''' <remarks></remarks>
    Private Sub DesktopSettingsGenerateMenuItems(ByVal Menu As ToolStripMenuItem)
        ' Clear out all previous menu items for desktop settings
        If Menu.DropDownItems.Count > 0 Then
            For i As Integer = Menu.DropDownItems.Count - 1 To 0 Step -1
                If Menu.DropDownItems(i).GetType Is GetType(uxViewDesktopSettingsMenuItem) Then
                    Menu.DropDownItems.RemoveAt(i)
                End If
            Next
        End If

        ' Add all new settings. Sort the list also?
        If Me.m_UserDesktopSettings.Count > 0 Then
            Dim menuItems(Me.m_UserDesktopSettings.Count - 1) As uxViewDesktopSettingsMenuItem

            ' Generate the menu items
            For i As Integer = 0 To menuItems.Length - 1
                menuItems(i) = New uxViewDesktopSettingsMenuItem()
                AddHandler menuItems(i).Click, AddressOf uxViewDesktopSettingsItem_Click
                menuItems(i).Name = Me.m_UserDesktopSettings(i).Name
                menuItems(i).Text = menuItems(i).Name
                menuItems(i).DesktopSettings = Me.m_UserDesktopSettings(i)
            Next

            ' Sort the array before adding it
            'Array.Sort(menuItems)

            ' Insert the menu items
            For i As Integer = 0 To menuItems.Length - 1
                Menu.DropDownItems.Insert(i, menuItems(i))
            Next
        End If

    End Sub

    ''' <summary>
    ''' Setup the save menu item so it appears nicley
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub uxViewDesktopSettings_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxViewDesktopSettings.DropDownOpening
        uxViewDesktopSettingsSave.Text = "Save """ & Me.m_UserDesktopSettings.CurrentDesktop.Name & """"
        uxViewDesktopSettingsDelete.Text = "Delete """ & Me.m_UserDesktopSettings.CurrentDesktop.Name & """"
    End Sub

    ''' <summary>
    ''' custom menu item class used for form menu's
    ''' </summary>
    ''' <remarks></remarks>
    Private Class uxViewDesktopSettingsMenuItem
        Inherits ToolStripMenuItem
        Implements IComparable(Of uxViewDesktopSettingsMenuItem)

        Private mSettings As UI.UserDesktopSettings

        Public Property DesktopSettings() As UI.UserDesktopSettings
            Get
                Return mSettings
            End Get
            Set(ByVal value As UI.UserDesktopSettings)
                mSettings = value
            End Set
        End Property

        Public Function CompareTo(ByVal other As uxViewDesktopSettingsMenuItem) As Integer Implements System.IComparable(Of uxViewDesktopSettingsMenuItem).CompareTo
            If Not IsNothing(other) Then
                If other.DesktopSettings.Name > Me.DesktopSettings.Name Then
                    Return 1
                Else
                    Return 0
                End If
            Else
                Return 0
            End If
        End Function
    End Class

#End Region

#Region "Private classes"
    Private Class DataStreamLogToolStripMenuItem
        Inherits ToolStripMenuItem

        Private mStartTime As DateTime = Nothing
        Private mLength As UInt32 = 0
        Private mName As String = ""

        ''' <summary>
        ''' Initialises a new datastrealog menu item
        ''' </summary>
        ''' <param name="text">text to display</param>
        ''' <param name="OnClick">on click event to use</param>
        ''' <param name="DataLog">Data Log Item to encapculate</param>
        ''' <remarks></remarks>
        Sub New(ByVal text As String, ByVal OnClick As System.EventHandler, ByVal DataLog As DataStream.StreamLogDBItem)
            MyBase.New(text, Nothing, OnClick)
            Me.mStartTime = DataLog.StartTime
            Me.mLength = DataLog.Length
            mName = DataLog.LogName
        End Sub

        Public ReadOnly Property LogStartTime() As DateTime
            Get
                Return mStartTime
            End Get
        End Property

        Public ReadOnly Property LogLength() As UInt32
            Get
                Return mLength
            End Get
        End Property

        Public ReadOnly Property LogName() As String
            Get
                Return mName
            End Get
        End Property

    End Class

#End Region

    Private Sub cnMViewReplay_VisibleChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnMViewReplay.VisibleChanged
        If Not IsNothing(m_newCar) AndAlso Not IsNothing(Me.m_newCar.StreamDB.CurrentStream) Then
            If Me.m_newCar.StreamDB.CurrentStream.StreamPlaying Then
                CType(sender, ToolStripMenuItem).Checked = True
            Else
                CType(sender, ToolStripMenuItem).Checked = False
            End If
        End If
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub

    Private Sub mVUserCalcs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mVUserCalcs.Click
        If Not IsNothing(m_newCar) Then
            Dim frm As New DataStream.StreamCalculatorConfigForm(m_newCar.StreamCalculator, m_newCar.StreamDB.CurrentStream)

            frm.Show()
        End If
    End Sub

    Public Event Close1(ByVal sender As Object, ByVal e As System.EventArgs) Implements DataStream.IStreamRecieve.Close

    Public Sub RecieveSeek(ByVal Stream As DataStream.Stream) Implements DataStream.IStreamRecieve.RecieveSeek

    End Sub

    Private Sub mFExportCurrentDatalog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mFExportCurrentDatalog.Click

        If Not IsNothing(m_newCar) AndAlso Not IsNothing(m_newCar.StreamDB.CurrentStream) Then

            If Me.uxExportDatalog.ShowDialog() = Windows.Forms.DialogResult.OK Then

                Dim fileOutput As IO.StreamWriter = Nothing
                Dim textOutput As TextWriterTraceListener = Nothing
                Try
                    fileOutput = New IO.StreamWriter(Me.uxExportDatalog.FileName)
                    textOutput = New TextWriterTraceListener(fileOutput)
                    Dim dataLog As DataStream.StreamLog = m_newCar.StreamDB.CurrentStream
                    Dim fieldNames As ObjectModel.Collection(Of String) = dataLog.ValidItems
                    Dim textDelimiter As String = ","

                    ' Write out the heading
                    For i As Integer = 0 To fieldNames.Count - 1
                        textOutput.Write(fieldNames(i) & textDelimiter)
                    Next
                    textOutput.WriteLine("")

                    ' Write out the data
                    For nCnt As Integer = 0 To dataLog.Count - 1
                        For i As Integer = 0 To fieldNames.Count - 1
                            If dataLog(nCnt).contains(fieldNames(i)) Then
                                textOutput.Write(dataLog(nCnt)(fieldNames(i)).Value.ToString & textDelimiter)
                            Else
                                textOutput.Write(textDelimiter)
                            End If
                        Next
                        textOutput.WriteLine("")
                    Next

                Catch ex As FieldAccessException
                    Err_message(ex.Message, message_type.MSG_Error)
                Finally
                    If Not IsNothing(textOutput) Then textOutput.Flush()
                    If Not IsNothing(fileOutput) Then fileOutput.Close()
                End Try
            End If
        Else
            Err_message("BikiRom file not open or current Datalog is empty or doesn't exist", message_type.MSG_Infomation)
        End If
    End Sub

    Private Sub ConfigureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConfigureToolStripMenuItem.Click
        Dim frm As New frmExtensions(Me.m_StreamRuntimeExtensions)
        frm.Show()
    End Sub

    Public ReadOnly Property Name1() As String Implements INamed.Name
        Get
            Return "BikiSoftMainForm"
        End Get
    End Property

    Private Sub TestButtonToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TestButtonToolStripMenuItem.Click
        Me.uxDockingPanel.SaveAsXml("c:\temp\layout.xml")
    End Sub

    Public ReadOnly Property RecieverType() As DataStream.StreamRecieveType Implements DataStream.IStreamRecieve.RecieverType
        Get
            Return DataStream.StreamRecieveType.eStreamConsumeOnly
        End Get
    End Property

    Private Sub uxMenuWindows_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuWindows.DropDownOpening
        For Each item As ToolStripMenuItem In CType(sender, ToolStripMenuItem).DropDownItems
            If IsNothing(item.Tag) Then
                item.Tag = Val(item.Text.Replace("&", ""))
                item.Text = Me.uxDockingPanel.DocumentsToArray(item.Tag - 1).DockHandler.TabText
            End If
        Next
    End Sub

    Private Sub uxBikiTestPattern_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxBikiTestPattern.Click
        Dim bStatus As Boolean = False
        Dim frm As New frmProgress("Verify Flash Banks")

        If BikiRom_Init() = BK_return.BK_OK Then
            Try
                Dim frame As Comm.Comm_Frame
                bStatus = True

                frm.Show()

                frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , BikiSoft.Comm.Comm_Frame.BikiFrameAction.RUN_DIAG_FLASH, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)

                If m_UsbCommHandler.SendFrame(frame) <> Comm.Comm_Frame.BikiFrameResponse.CMD_PASSED Then
                    bStatus = False

                    frm.AddMessage("Flash Bank 1 Failed to verify")
                End If

                If m_UsbCommHandler.BoardVersion = Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV3 Then
                    frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , BikiSoft.Comm.Comm_Frame.BikiFrameAction.RUN_DIAG_FLASH2, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                    If m_UsbCommHandler.SendFrame(frame) <> Comm.Comm_Frame.BikiFrameResponse.CMD_PASSED Then
                        bStatus = False
                        frm.AddMessage("Flash Bank 2 Failed to verify")
                    End If
                End If

            Catch ex As Comm_Exceptions
                bStatus = False
                frm.AddMessage("Communication Error or Timeout")
            End Try

            If bStatus Then
                frm.AddMessage("Flash Banks Verified")
            End If

            MsgBox("Tests Complete")

            frm.Close()
        Else
            MsgBox("Unable to connect to board, ensure ecu is turned on")
        End If

    End Sub

    Private Sub uxBikiTestBanks_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxBikiTestBanks.Click
        Dim bStatus As Boolean = False
        Dim frm As New frmProgress("Writing Test Pattern")


        If MsgBox("THIS OPERATION WILL ERASE YOUR BOARD. BE SURE TO BACKUP YOUR DATA BEFORE PERFORMING THIS TEST!", MsgBoxStyle.Exclamation And MsgBoxStyle.OkCancel, "WARNING!!!!!") = MsgBoxResult.Ok Then
            If BikiRom_Init() = BK_return.BK_OK Then
                Try
                    Dim frame As Comm.Comm_Frame

                    bStatus = True

                    frm.Show()

                    frm.AddMessage("These tests can take up to 1 minute. The screen may appear to be locked")

                    m_UsbCommHandler.Timeout = 60000

                    frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , BikiSoft.Comm.Comm_Frame.BikiFrameAction.RUN_ERASEBANK1, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                    If m_UsbCommHandler.SendFrame(frame) <> Comm.Comm_Frame.BikiFrameResponse.CMD_OK Then
                        bStatus = False
                        frm.AddMessage("Failed to erased Flash 1")
                    Else
                        frm.AddMessage("Erased Flash 1 OK")
                    End If

                    If m_UsbCommHandler.BoardVersion = Comm.UsbBikiromInformation._BoardVersion.BikiRomUSBV3 Then
                        frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , BikiSoft.Comm.Comm_Frame.BikiFrameAction.RUN_ERASEBANK2, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                        If m_UsbCommHandler.SendFrame(frame) <> Comm.Comm_Frame.BikiFrameResponse.CMD_OK Then
                            bStatus = False
                            frm.AddMessage("Failed to erased Flash 2")
                        Else
                            frm.AddMessage("Erased Flash 2 OK")
                        End If
                    End If

                    If bStatus Then

                        Threading.Thread.Sleep(100)

                        frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , BikiSoft.Comm.Comm_Frame.BikiFrameAction.RUN_TEST_WRITE_PATTERN, , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                        If m_UsbCommHandler.SendFrame(frame) <> Comm.Comm_Frame.BikiFrameResponse.CMD_PASSED Then
                            bStatus = False
                            frm.AddMessage("Failed to write test pattern")
                        Else
                            frm.AddMessage("Wrote Test Pattern ok! Flash is 100% OK")
                        End If
                    End If

                Catch ex As USB_exceptions
                    bStatus = False

                Catch ex As Comm_Exceptions
                    bStatus = False
                End Try

                If Not bStatus Then
                    frm.AddMessage("Writing test pattern not possible or failed, flash error(s) on board")
                End If

                frm.ControlBox = True

                MsgBox("Tests Complete, See status window for results")
            Else
                MsgBox("Unable to connect to board, ensure ecu is turned on")
            End If
        End If
    End Sub

    Private Sub uxMenuView_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuView.DropDownOpening
        mV3d.Checked = Me.uxBarGraph3d.Visible
        mV2Dtrace.Checked = Me.uxBarGraph.Visible
    End Sub

    Private Sub tmrTestGrid_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrTestGrid.Tick
        If Not IsNothing(m_newCar) Then
            If Me.uxDockGrids.Count Then
                Dim grid As Controls.DataGrid = Me.uxDockGrids(0).Controls(0)
                Dim point As PointF = grid.TracePoint

                Dim points As Point() = grid.EmuTracePoints

                If IsNothing(points) Then ReDim points(3)

                point.X = Math.Min(point.X + 0.1, grid.ColumnCount - 1)
                point.Y = Math.Min(point.Y + 0.1, grid.RowCount - 1)

                If point.X = grid.ColumnCount - 1 Then point.X = 0
                If point.Y = grid.ColumnCount - 1 Then point.Y = 0

                points(0).X = Math.Min(Math.Truncate(point.X), grid.ColumnCount - 2)
                points(0).Y = Math.Min(Math.Truncate(point.Y), grid.RowCount - 2)
                points(1).X = Math.Min(Math.Truncate(point.X + 1), grid.ColumnCount - 1)
                points(1).Y = Math.Min(Math.Truncate(point.Y), grid.RowCount - 2)
                points(2).X = Math.Min(Math.Truncate(point.X + 1), grid.ColumnCount - 1)
                points(2).Y = Math.Min(Math.Truncate(point.Y + 1), grid.RowCount - 1)
                points(3).X = Math.Min(Math.Truncate(point.X), grid.ColumnCount - 2)
                points(3).Y = Math.Min(Math.Truncate(point.Y + 1), grid.RowCount - 1)

                grid.TracePoint = point
                grid.EmuTracePoints = points

            End If
        End If
    End Sub

    Private Sub uxDataLoggingOverlay_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxDataLoggingOverlay.CheckedChanged

    End Sub
End Class